深入解析Vue源码实例挂载与编译流程实现思路详解

  

在正文开始之前,先了解vue基于源码构建的两个版本,一个是<代码>运行>//需要编译器的版本   新Vue ({   模板:“& lt; div>{{嗨}}& lt;/div>”   })      

  

vue挂载的流程是比较复杂的,我们通过流程图理清基本的实现思路。

  

深入解析Vue源码实例挂载与编译流程实现思路详解

  

如果用一句话概括挂载的过程,可以描述为挂载组件,将渲染函数生成虚拟DOM,更新视图时,将虚拟DOM渲染成为真正的DOM。

  

详细的过程是:首先确定挂载的DOM元素,且必须保证该元素不能为html,身体这类跟节点。判断选项中是否有渲染这个属性(如果不在运行时编译,则在选项初始化时需要传递渲染渲染函数)。当有渲染这个属性时,默认我们使用的是运行时只的版本,从而跳过模板编译阶段,调用真正的挂载函数美元。另一方面,当我们传递是模板模板时(即在不使用外置编译器的情况下,我们将使用运行时+编译的版本),Vue源码将首先进入编译阶段。该阶段的核心是两步,一个是把模板解析成抽象的语法树,也就是我们常听到的AST,第二个是根据给定的AST生成目标平台所需的代码,在浏览器端是前面提到的渲染函数。完成模板编译后,同样会进美元入山挂载阶段。真正的挂载过程,执行的是mountComponent方法,该函数的核心是实例化一个渲染观察家,具体观察者的内容,另外放章节讨论。我们只要知道渲染观察者的作用,一个是初始化的时候会执行回调函数,另一个是当vm实例中监测的数据发生变化的时候执行回调函数。而这个回调函数就是updateComponent,这个方法会通过vm。_render生成虚拟DOM,并最终通过<代码> vm。DOM _update>   

往下,我们从代码的角度出发,了解一下挂载的实现思路,下面只提取骨山架代码说明。

     //内部真正实现挂载的方法   Vue.prototype。美元=function山(el保湿){   el=,,inBrowser & # 63;查询(el):定义;//调用mountComponent方法挂载   返回mountComponent (el,保湿)   };//缓存了原型上的美元山方法   var=Vue.prototype山。山美元;//重新定义,美元为包含编译器和不包含编译器的版本提供不同封装,最终调用的是缓存原型上的美元山方法   Vue.prototype。美元=function山(el保湿){//获取挂载元素   el=,,查询(el);//挂载元素不能为跟节点   如果文档(el===I硖鍇 | el===document.documentElement) {   警告(   “别山Vue & lt; html>或& lt; body>——正常的元素而不是山。”   );   返回这   }   美元var=这个选项。选项;//需要编译或不需要编译   如果(! options.render) {   ···//使用内部编译器编译模板   }//最终调用缓存美元的山方法   返回山。调用(el,保湿)   }//mountComponent方法思路   函数mountComponent (vm, el,补水){//定义updateComponent方法,在看回调时调用。   updateComponent=function () {//渲染函数渲染成虚拟DOM,虚拟DOM渲染成真实的DOM   vm._update (vm._render(),保湿);   };//实例化渲染观察者   新观察家(vm, updateComponent,等待,{})   }      

  

通过文章前半段的学习,我们对Vue的挂载流程有了一个初略的认识。接下来将先从模板编译的过程展开。阅读源码时发现,模板的编译过程是相当复杂的,要在短篇幅内将整个编译的过程讲开是不切实际的,因此这节剩余内容只会对实现思路做简单的介绍。

  

<>强3.3.1模板的三种写法

  

模板模板的编写有三种方式,分别是:

     //1。熟悉的字符串模板   var vm=new Vue ({   埃尔:“#应用”,   模板:“& lt; div>模板字符串& lt;/div>”   })//2。选择符匹配元素的innerHTML模板   & lt; div id=坝τ谩北?   & lt; div> test1
  & lt;脚本类型=" x-template " id=安馐浴北?   & lt; p> test

  & lt;/script>   & lt;/div>   var vm=new Vue ({   埃尔:“#应用”,   模板:“#测试”   })//3。dom元素匹配元素的innerHTML模板   & lt; div id=坝τ谩北?   & lt; div> test1
  & lt;跨度id=安馐浴弊4? lt; div类=皌est2祝辞test2