每天学点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中rem的配置的方法示例

    当我们在使用vue框架开发网站时,经常需要使用rem单位进行网站的样式设计,然而,在不同的屏幕大小下,rem的大小也需要跟着变化,因此我们需要针对不同的屏幕尺寸去设置不同的rem大小。以下是在vue中配置rem的方法示例。 一、安装插件 在vue中配置rem需要使用一个插件,即postcss-pxtorem,我们可以通过以下命令进行安装: npm insta…

    Vue 2023年5月28日
    00
  • Vue编写炫酷的时钟插件

    下面是Vue编写炫酷的时钟插件的完整攻略。 步骤1:创建Vue项目 首先我们需要创建一个Vue项目,在终端中执行以下命令: vue create vue-clock 然后在创建的项目中找到src/components目录,创建一个Clock.vue组件用于编写时钟插件。 步骤2:编写HTML结构和CSS样式 在Clock.vue组件中,我们需要编写HTML结…

    Vue 2023年5月29日
    00
  • electron实现静默打印的示例代码

    下面我来详细讲解一下如何使用Electron实现静默打印的示例代码,包括如何设置打印机、如何导出PDF、如何调用打印机等过程。 1. 设置打印机 在electron中实现静默打印首先需要设置打印机。可以通过Electron中的打印功能来获取电脑上所有的可用打印机。代码如下: const {BrowserWindow} = require(‘electron’…

    Vue 2023年5月28日
    00
  • Vue2.0如何发布项目实战

    Vue2.0是一个非常流行的前端框架,使用Vue2.0发布项目需要进行以下步骤: 1. 安装Vue脚手架 在开始之前,我们需要安装Vue脚手架。我们可以使用npm来安装: npm install -g vue-cli 安装完成后,我们可以使用以下命令来创建Vue项目模板: vue init webpack my-project 这里的“my-project”…

    Vue 2023年5月28日
    00
  • 使用Vue生成动态表单

    关于使用Vue生成动态表单的完整攻略,我们可以分为以下几个步骤: 步骤一:设计表单数据结构 首先,我们需要根据需求设计表单数据结构,包括表单元素类型、名称、value、placeholder、校验规则等信息。可以采用JSON格式来设计。 例如,我们要生成一个带有输入框、下拉框、单选框、多选框等元素的表单,可以按照如下格式来设计表单数据结构: formItem…

    Vue 2023年5月28日
    00
  • vue动态渲染svg、添加点击事件的实现

    为了实现vue动态渲染svg以及添加点击事件,需要采用SVG语言作为矢量图形语言,使用vue指令中的v-html渲染SVG字符串,以及添加@click事件监听器。 实现步骤: 准备SVG字符串。可以是文件、变量定义或远程获取的内容。例如以下的SVG字符串: <svg width="100" height="100&quot…

    Vue 2023年5月28日
    00
  • Vue事件修饰符使用详细介绍

    下面是Vue事件修饰符的详细介绍。 一、Vue事件修饰符简介 在Vue中,事件修饰符是用来处理DOM事件的修饰符的一种方式。通过使用事件修饰符,我们可以在触发DOM事件时,修改事件的行为或者触发条件,达到更加灵活的控制页面交互效果和事件处理。 Vue中提供了多种事件修饰符,包括.stop、.prevent、.capture、.self、.once、.pass…

    Vue 2023年5月28日
    00
  • vue用Object.defineProperty手写一个简单的双向绑定的示例

    下面是Vue用Object.defineProperty手写一个简单的双向绑定的攻略。 双向绑定是指当数据改变时,视图也会随之更新,而当视图改变时,数据也会随之更新。Vue是一款双向绑定的框架,它通过观察者模式实现了数据与视图的同步更新。其核心原理就是利用Object.defineProperty()方法对数据进行拦截和劫持,实现数据变更时视图的更新操作。下…

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