每天学点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日

相关文章

  • Vue3计算属性和异步计算属性方式

    Vue3中计算属性和异步计算属性的使用方式与Vue2有所不同。接下来将详细讲解Vue3计算属性和异步计算属性的使用方式,并附上两个示例说明。 Vue3计算属性 Vue3中,计算属性仍然是一个非常重要的概念,主要是为了方便我们处理模板中的复杂计算逻辑。Vue3计算属性的使用方法与Vue2基本相同。 基本使用 在Vue3中,可以通过computed选项来定义计算…

    Vue 2023年5月28日
    00
  • vue生成文件本地打开查看效果的实例

    让我来详细讲解一下“Vue生成文件本地打开查看效果的实例”的完整攻略。整个过程分为以下几个步骤: 1. 安装Vue Cli 首先,我们需要全局安装Vue的脚手架工具Vue Cli。可以使用以下命令进行安装: npm install -g @vue/cli 2. 创建Vue项目 使用Vue Cli创建一个新的Vue项目。 vue create my-proje…

    Vue 2023年5月28日
    00
  • 使用 Vue 绑定单个或多个 Class 名的实例代码

    下面是详细讲解使用Vue绑定单个或多个Class名的实例代码的完整攻略: Vue绑定单个Class名 示例说明: 在模板中使用v-bind或简写形式:来绑定class,需要将要绑定的class名作为一个JavaScript表达式。 方式一:对象语法 绑定单个class名的方式一:对象语法 <template> <div :class=&qu…

    Vue 2023年5月28日
    00
  • echarts报错:Error in mounted hook的解决方法

    下面是关于”echarts报错:Error in mounted hook的解决方法”的完整攻略。 什么是“echarts报错:Error in mounted hook”的问题? 当使用 echarts 绘制图表时,有时在控制台会看到一个错误提示:“Error in mounted hook”,通常提示中还会包含一些错误信息,比如:“Cannot read…

    Vue 2023年5月27日
    00
  • 详解Vue 中 extend 、component 、mixins 、extends 的区别

    让我详细讲解一下“详解Vue 中 extend 、component 、mixins 、extends 的区别”。 extend extend是Vue实例的一个方法,在使用时需要首先通过调用该方法来创建一个构造函数,然后通过该构造函数来创建Vue实例。 示例: // 创建一个名为MyComponent的构造函数 const MyComponent = Vue…

    Vue 2023年5月28日
    00
  • 使用vue中的v-for遍历二维数组的方法

    使用vue中的v-for可以快速方便地遍历数组,但是遍历二维数组需要一些特殊的处理方法。以下是遍历二维数组的方法: 方法一:使用两个嵌套的v-for循环 我们可以使用两个嵌套的v-for循环来遍历二维数组。外层循环遍历一维数组,内层循环遍历二维数组,这样可以逐个输出二维数组的每个元素。 <div v-for="(oneDimensionalA…

    Vue 2023年5月29日
    00
  • Java Socket编程服务器响应客户端实例代码

    Java Socket编程是一种网络编程方法,用于在客户端和服务器端之间建立连接,并进行数据传输。在Java中,可以使用Socket和ServerSocket类实现Socket编程。客户端使用Socket类创建连接,服务器端使用ServerSocket类监听连接请求。在本篇文章中,我们将为你提供 “Java Socket编程服务器响应客户端实例代码”的完整攻…

    Vue 2023年5月28日
    00
  • 简单了解Vue computed属性及watch区别

    下面就是“简单了解Vue computed属性及watch区别”的完整攻略。 一、computed属性 在Vue中,computed属性是一个带有缓存的计算属性,也就是说,computed属性只会在它依赖的数据发生变化时才会重新计算一次,否则会直接返回之前缓存的结果。 1.1 定义computed属性 computed属性的定义类似于Vue的数据属性,你可以…

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