文章目录
- 前言
- 一、使用Runtime+Compiler解析$mount的原因
- 二、$mount 解析的详细过程
- 1.解析挂载的#app执行了vm.$mount
- 2. 通过$mount方法执行以下文件的mount方法
- 3. 执行util工具文件夹中的query方法
- 4. 执行query方法后返回$mount方法判断el是否是body
- 5. 判断!options.render
- (1)options.render是否为真
- (2)判断是否使用了template
- (3)判断是否是el
- (4)返回的 mount 的方法
- 6. 解析mountComponent方法
- 总结
前言
Runtime Only 和 Runtime+Compiler的区别
通常我们利用 vue-cli 去初始化我们的 Vue.js 项目的时候会询问我们用Runtime Only 版本的还是 Runtime+Compiler 版本。
Runtime Only:我们在使用 Runtime Only 版本的 Vue.js 的时候,通常需要借助如 webpack的 vue-loader 工具把 .vue 文件编译成 JavaScript,因为是在编译阶段做的,所以它只包含运行时的 Vue.js 代码,因此代码体积也会更轻量。
Runtime+Compiler:我们如果没有对代码做预编译,但又使用了 Vue 的 template 属性并传入一个字符串,则需要在客户端编译模板。如下所示:
// 需要编译器的版本
new Vue({
template: '<div>{{ hi }}</div>'
})
// 这种情况不需要
new Vue({
render (h) {
return h('div', this.hi)
}
因为在 Vue.js 2.0 中,最终渲染都是通过 render 函数,如果写 template 属性,则需要编译成 render 函数,那么这个编译过程会发生运行时,所以需要带有编译器的版本。
很显然,这个编译过程对性能会有一定损耗,所以通常我们更推荐使用Runtime-Only 的 Vue.js。
一、使用Runtime+Compiler解析$mount的原因
Vue中我们通过
$mount
方法去挂载vm,而$mount
方法在多个文件中都有定义。如源码src\platforms\web\runtime\index.ts
、src\platforms\web\runtime-with-compiler.ts
等文件。由于使用纯前端的方式分析源码,所以我这里分析 Compiler 版本的 $mount,有利于对原理深入的理解。
src\platforms\web\runtime\index.ts的方法较为简单,如下图
二、$mount 解析的详细过程
1.解析挂载的#app执行了vm.$mount
2. 通过$mount方法执行以下文件的mount方法
路径:
src\platforms\web\runtime-with-compiler.ts
3. 执行util工具文件夹中的query方法
路径:
src\platforms\web\util\index.ts
也就是main.js 中el: ‘#app’ 传入的话,就会执行1.1获取对应的元素
4. 执行query方法后返回$mount方法判断el是否是body
5. 判断!options.render
(1)options.render是否为真
下一章节会详细讲解
(2)判断是否使用了template
也就是使用
Runtime Only
需要编译的写法,这个在前言中详细说明了,可以返回顶部详细看看。
// 使用了template配置的写法
import Vue from 'vue'
var app = new Vue({
el: '#app',
template: '<div>{{ message }}</div>', // 使用了template
data() {
return {
message: '我是一个双向绑定的数据'
}
}
})
(3)判断是否是el
如果是el,就执行getOutHtml方法,获取main.js中el的id名的div元素
(4)返回的 mount 的方法
路径:src\platforms\web\runtime\index.ts
6. 解析mountComponent方法
路径
src\core\instance\lifecycle.ts
执行updateComponent方法,通过Watcher根据数据更新执行。感兴趣可以查看Watcher里面的配置即可。
总结
这就是$mount 挂载的过程