每天学点Vue源码之vm.$mount挂载函数

讲解“每天学点Vue源码之vm.$mount挂载函数”的完整攻略。

什么是vm.$mount挂载函数?

vm.$mount 是 Vue 实例的 $mount() 函数,用于把Vue实例挂载到页面中的元素上。该函数有两种使用方式:

1.手动挂载

在手动挂载时,可以通过引入 Vue.js,创建 Vue 实例并手动挂载到一个DOM上。具体代码如下:

<!-- 在DOM中定义一个空白的DIV元素 -->
<div id="app"></div>

<!-- 引入Vue.js -->
<script src="https://cdn.jsdelivr.net/npm/vue"></script>

<script>
// 创建Vue实例
var vm = new Vue({
  el: '#app', // 指定挂载元素
  data: {
    message: 'Hello Vue!'
  }
})
</script>

2.运行时编译挂载

在运行时编译时,可以通过使用 webpack 或者 vue-loader 等构建工具对 Vue 代码进行编译,自动挂载到相应的DOM元素上。该方式需要在 Vue 中进行配置。具体代码如下:

<!-- 在DOM中定义一个空白的DIV元素 -->
<div id="app"></div>

<!-- 引入Vue.js -->
<script src="https://cdn.jsdelivr.net/npm/vue"></script>

<script>
// 创建Vue实例
var vm = new Vue({
  template: '<div>Hello {{name}}!</div>',
  data: {
    name: 'Vue'
  }
})

// 运行时编译挂载
vm.$mount('#app')
</script>

$mount挂载函数的具体实现

在 Vue.js 的源码中,$mount 函数主要实现了以下几个过程:

  1. 初始化组件

首先会进行组件实例化的初始化,在使用 new Vue() 创建一个 Vue 实例时,会自动调用 _init() 来进行初始化。在 部分源码如下:

Vue.prototype._init = function (options) {
  const vm = this
  vm._uid = uid++ // 增加_uid属性,用于标识唯一的实例ID
  let startTag, endTag // 定义起始标签和结束标签

  // 如果启动生产模式,进行模板语法错误检查
  if (process.env.NODE_ENV !== 'production' && config.performance && mark) {
    startTag = `vue-perf-start:${vm._uid}`
    endTag = `vue-perf-end:${vm._uid}`
    mark(startTag)
  }

  // 定义_isVue标记
  vm._isVue = true
  // Merge options
  if (options && options._isComponent) { // 处理组件的逻辑
    initInternalComponent(vm, options)
  } else { // 处理普通Vue实例的逻辑
    vm.$options = mergeOptions(
      resolveConstructorOptions(vm.constructor),
      options || {},
      vm
    )
  }

  // ...
}
  1. 获取挂载点元素

接着,会获取到传递的参数,并以此获取到el元素。如果 el 元素不存在,需要通过 template 或者手动在代码中创建一个新的 DOM 元素并挂载到身上来。具体源码如下:

Vue.prototype.$mount = function (el?: string | Element, hydrating?: boolean): Component {
  // ...

  // 获取挂载的DOM元素
  const options = this.$options
  if (!options.render) {
    let template = options.template
    if (template) { // 处理template属性
      if (typeof template === 'string') {
        if (template.charAt(0) === '#') {
          template = idToTemplate(template)
          /* istanbul ignore if */
          if (process.env.NODE_ENV !== 'production' && !template) {
            warn(
              `Template element not found or is empty: ${options.template}`,
              this
            )
          }
        }
      } else if (template.nodeType) { // template是元素节点(不常用)
        template = template.innerHTML
      } else {
        if (process.env.NODE_ENV !== 'production') {
          warn('invalid template option:' + template, this)
        }
        return this
      }
    } else if (el) { // 如果没有template属性,就将el作为模板并获取内部HTML
      template = getOuterHTML(el)
    }

    // 如果解析到了template模板,则进行编译
    if (template) {
      const { render, staticRenderFns } = compileToFunctions(
        template,
        {
          outputSourceRange: process.env.NODE_ENV !== 'production',
          shouldDecodeNewlines,
          shouldDecodeNewlinesForHref,
          delimiters: options.delimiters,
          comments: options.comments
        },
        this
      )
      options.render = render
      options.staticRenderFns = staticRenderFns
    }
  }

  // ...
}
  1. 进行组件挂载

最后一个关键步骤是进行组件挂载。具体过程中,会判断是否有渲染函数(render),如果没有,则生成一个渲染函数并准备对渲染函数进行编译。如果有,就把渲染函数转换成可执行的 vdom。具体源码如下:

Vue.prototype.$mount = function (el?: string | Element, hydrating?: boolean): Component {
  // ...

  // 如果没有渲染函数,则生成一个渲染函数
  if (!options.render) {
    render = noop
    // 对模板进行编译(这个需要单独介绍)
    const template = options.template
    if (template) {
      // ...
    } else if (el) {
      // ...
    }
  }

  // ...
  // 挂载组件
  const updateComponent = () => {
    vm._update(vm._render(), hydrating)
  }
  // ...
}

两个 $mount 挂载函数的详细示例

下面给出两个 $mount 挂载函数的示例。

示例1:手动挂载Vue实例

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>Demo-example-1</title>
    <script src="../js/vue.js"></script>
  </head>
  <body>
    <div id="example">{{ msg }}</div>
  </body>
</html>
var app = new Vue({
  el: '#example',
  data: {
    msg: 'Hello, Vue!'
  }
})

在这个例子中,手动创建 Vue 实例 app,并手动将其挂载到 DOM 元素 #example 上。msg 属性的初始值是 "Hello, Vue!"。

示例2:运行时编译挂载

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>Demo-example-2</title>
    <script src="../js/vue.js"></script>
  </head>
  <body>
    <div id="app"></div>
  </body>
  <script>
    const app = new Vue({
      template: '<div>Hello {{ name }}!</div>',
      data: {
        name: 'Vue'
      }
    })
    app.$mount('#app')
  </script>
</html>

在这个例子中,运行时编译时,传入 template 属性并定义了对应的数据属性。在 $mount 方法执行时,会将传入的 template 编译成 render 函数并执行挂载。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:每天学点Vue源码之vm.$mount挂载函数 - Python技术站

(0)
上一篇 2023年5月28日
下一篇 2023年5月28日

相关文章

  • Vue中v-on的基础用法、参数传递和修饰符的示例详解

    下面我会详细讲解“Vue中v-on的基础用法、参数传递和修饰符的示例详解”。 1. v-on的基础用法 v-on是Vue的事件绑定指令,它可以监听指定的DOM事件,并在事件触发时执行指定的Vue方法。v-on的基础用法格式为:v-on:事件名=”方法名”,其中事件名可以是任意合法的DOM事件名,方法名则是Vue实例的一个方法名。示例代码: <butto…

    Vue 2023年5月28日
    00
  • VUE写一个简单的表格实例

    下面是使用VUE.js编写一个简单的表格实例的完整攻略: 步骤一:创建VUE.js实例 首先,我们需要在HTML中引入VUE.js的JavaScript文件,然后再创建一个VUE的实例,代码如下: <!DOCTYPE html> <html> <head> <meta charset="utf-8&quot…

    Vue 2023年5月29日
    00
  • Vue.js中的计算属性、监视属性与生命周期详解

    Vue.js中的计算属性、监视属性与生命周期详解 计算属性 什么是计算属性 计算属性(computed)是Vue.js内置的一个特殊属性,可以定义一个依赖其它属性的计算属性,而这个计算属性的值会被缓存起来,在某些需要频繁用到的属性计算中,计算属性会比直接通过方法计算效率更高,因为计算属性是有缓存的,只有在它的相关属性发生改变时才会重新计算,否则直接取缓存值。…

    Vue 2023年5月28日
    00
  • vue中destroyed方法的使用说明

    当一个组件(component)被销毁时,Vue 会自动调用该组件的生命周期钩子函数 destroyed。destroyed 生命周期是在组件的程序和网络活动结束后被调用的,并且在其它生命周期钩子函数后执行。这意味着 Vue 实例及其数据观察者已被解绑定,所有的事件监听器和子组件已被移除,所有的计时器和异步任务已被清理。下面就详细讲解 destroyed 方…

    Vue 2023年5月28日
    00
  • 如何使用 vue-cli 创建模板项目

    当您开始使用Vue.js开发项目时,使用vue-cli来创建模板项目将是一种非常有效的方式。下面将详细讲解如何使用vue-cli来创建基本的Vue.js项目模板。 步骤一:安装vue-cli 首先需要确保您的系统中已经安装了Node.js和npm。打开终端并执行以下命令安装vue-cli: npm install -g vue-cli 步骤二:创建一个新项目…

    Vue 2023年5月27日
    00
  • Vue 简单实现前端权限控制的示例

    针对 “Vue 简单实现前端权限控制的示例” 的完整攻略,我将分为以下几个部分进行详细的讲解: 前期准备 实现权限控制的方式 示例说明 前期准备 在进行权限控制的实现之前,我们需要提前做好以下几点准备: 熟悉 Vue 的基础语法和组件开发模式 新建一个项目并安装相关依赖,如 vue-router、axios 等 实现权限控制的方式 方式一:路由权限控制 Vu…

    Vue 2023年5月28日
    00
  • Leaflet 数据可视化实现地图下钻示例详解

    Leaflet 数据可视化实现地图下钻示例详解 本文将通过两个示例详细讲解如何使用 Leaflet 实现地图下钻的效果。 示例一:中国省市下钻 首先,利用官方提供的 GeoJSON 数据源,绘制中国地图。 javascript L.geoJSON(chinaData, { style: function (feature) { return { fillCo…

    Vue 2023年5月28日
    00
  • vue 数组添加数据方式

    下面是“Vue 数组添加数据方式”完整攻略。 前置知识: 在了解Vue中的数组添加数据方式之前,我们需要了解Vue中的响应式原理。Vue在渲染页面时,会做一个数据变更监听,当数据发生变化时,它会尝试重新渲染页面。数组在JS中是通过push和pop等方法改变数据,但这些方法不会触发数组的变更监听。因为这个原因,Vue提供了一些可以触发变更监听的数组方法。 通过…

    Vue 2023年5月27日
    00
合作推广
合作推广
分享本页
返回顶部