>[success] # Vue -- $mount 模板编译阶段 * 注先跳过初始化的其他阶段,先分析'模板编译阶段' ~~~ 1.配合生命周期图和对'initMixin' 方法中最后一段的代码,可以理解下一步需要分析'模板编译阶段' if (vm.$options.el) { vm.$mount(vm.$options.el) } ~~~ ![](https://img.kancloud.cn/13/14/13141c8cea9139bb9416f6c853e48d56_757x428.png) >[danger] ##### 抛出几个问题 ~~~ 1.在利用'vue-cli3.0'搭建项目时候,一般生成的入口文件代码如下 import Vue from "vue"; import App from "./App.vue"; Vue.config.productionTip = false; new Vue({ render: h => h(App) }).$mount("#app"); 在这种非构建项目页面常见的用法: var vm = new Vue({ // 也可以绑定document.getElementById('app')返回的app对象 el: "#app", data: { msg: "第一个案例" } }) 这两种区别在哪里? 2.vue在使用的时候我们要绑定根节点,一般是在el属性,绑定声明的id,那还有其他方法可以绑定么? 3.vue 在绑定的时候可以绑定在'body' 和'html' 标签上么? ~~~ >[info] ## 开始分析编译阶段的源码 ~~~ 1.首先,要明确第一点,写到这里的时候我还没学到react,但从已经知道信息来说,React是没有模板的,直接就是一 个渲染函数,它中间返回的就是一个虚拟DOM树 2.Vue这里我先抛开通过'vue-loader'来做的项目(就例如你用vue脚手架,或者用webpack时候使用了'vue-loader') ,除此之外作为vue使用的开发大部分时间我们是写模板(可以理解正常html方式),这全得益于: 'Vue的编译器在编译模板之后,会把这些模板编译成一个渲染函数'而函数被调用的时候就会渲染并且返回一个虚拟 DOM的树 3.通过这里可以发现Vue为什么可以好上手主要原因也得益于不需要我们去写渲染函数内部转换机制可以帮我们解决 这个问题,当然你也可以直接写渲染函数,这样直接可以跳过vue帮忙转换的这部分 4.现在新的问题是vue 和react 为什么会选择使用'渲染函数' 这种解决方案?这里就不得不说 '在浏览器当中,JavaScript的运算在现代的引擎中非常快,但DOM本身是非常缓慢的东西' 当你调用原生DOM API的时候,浏览器需要在JavaScript引擎的语境下去接触原生的DOM的实现, 这个过程有相当的性能损耗。所以,本质的考量是,要把耗费时间的操作尽量放在纯粹的计算中去做, 保证最后计算出来的需要实际接触真实DOM的操作是最少的。 5.解答一下第四条,正式因为如此Vue 和react 选择使用'渲染函数', '函数被调用的时候就会渲染并且返回一个虚拟DOM的树',渲染函数(jsx)实际就是一套用于让我们更简单地去 描述树状结构的语法糖。 6.引入了新的概念虚拟DOM,什么是虚拟DOM? '所谓虚拟DOM,就是用一个JS对象来描述一个DOM节点',我们把组成一个DOM节点的必要东西通过一个 JS对象表示出来,那么这个JS对象就可以用来描述这个DOM节点,我们把这个JS对象就称为是这个真实 DOM节点的虚拟DOM节点。例如: <div class="a" id="b">我是内容</div> { tag:'div', // 元素标签 attrs:{ // 属性 class:'a', id:'b' }, text:'我是内容', // 文本内容 children:[] // 子元素 } 7.Vue'有了这个虚拟的树之后,再交给一个patch函数,负责把这些虚拟DOM真正施加到真实的DOM上',这样 原本直接操作真实DOM是非常消耗性能方式,我们利用虚拟dom节点这种方式,用JS的计算性能来换取操作 DOM所消耗的性能,我们可以简单的描述一下vue 这个过程: Vue有自身的响应式系统来侦测在渲染过程中所依赖到的数据来源。在渲染过程中,侦测到的数据来源之后, 之后就可以精确感知数据源的变动。到时候就可以根据需要重新进行渲染。当重新进行渲染之后,会生成 一个新的树,将新树与旧树进行对比,就可以最终得出应施加到真实DOM上的改动。最后再通过patch函数 施加改动。 ~~~ * vue 使用模板的时候vue内部帮我们做的 ![](https://img.kancloud.cn/7d/58/7d58c79b24e647af1d63fd9d4c965ea3_640x210.png) * vue 模板渲染过程 :模板 → 渲染函数 → 虚拟DOM树 → 真实DOM ![](https://img.kancloud.cn/c8/16/c816fc7b7cdbaeea70ed5dee58dc0251_1240x230.png) * 参考文章 [Vue作者尤雨溪:Vue 2.0,渐进式前端解决方案 ](https://mp.weixin.qq.com/s?__biz=MzUxMzcxMzE5Ng==&mid=2247485737&idx=1&sn=14fe8a5c72aaa98c11bf6fc57ae1b6c0&source=41#wechat_redirect) >[danger] ##### 官方文档内容 [模板编译](https://cn.vuejs.org/v2/guide/render-function.html#%E6%A8%A1%E6%9D%BF%E7%BC%96%E8%AF%91)