Vue加载流程

1.初始化的第一阶段是Vue实例也就是vm对象创立前后:首先Vue进行生命周期,事件初始化产生在beforeCreate生命周期函数前,而后进行数据监测和数据代理的初始化,也就是创立vm对象的过程,当vm对象创立实现就能够通过vm对象拜访到劫持的数据,比方data中的数据,methods中的办法等。而后Vue调用外部的render函数开始解析模板将其解析为一个JS对象也即在内存中生成虚构DOM也就是Vnode对象。第二阶段是vm对象挂载前后:挂载实现前页面出现的是未通过Vue编译的DOM构造,所有对DOM的操作最终都不会失效。挂载前首先将内存中的Vnode转换为实在DOM插入页面,此时实现挂载。页面中出现的就是通过Vue编译的DOM构造,至此初始化过程完结。

2.开启订阅音讯也就是数据劫持代理监听,其实就是写了一个watcher函数去监听数据的扭转,发送网络申请,绑定自定义事件等初始化操作。当数据发生变化当前即状态变更的时候,会从新结构新的Vnode对象。而后用新的Vnode对象和旧的Vnode对象进行差别比拟也就是DIFF算法,而后把差别利用到旧的Vnode对象所构建的真正的DOM树上这个过程就是patch,视图就更新了

每一个组件在加载时都会调用Vue外部的render函数把该组件的tamplate选项的模板解析为一个JS对象,这个对象和DOM节点对象构造一样,而后是数据劫持代理监听,当数据发生变化当前,将旧Vnode对象和生成的新Vnode对象比拟差别而后更新DOM

Vnode: {tag:"", id:, name:"Box", $el:实在页面上的DOM的援用, //等等属性 chiren:[ { tag:"", id:, name:"Box2",$el:实在页面上的DOM的援用, //等等属性 }, { tag:"", id:, name:"Box3",$el:实在页面上的DOM的援用,//等等属性 }] }

什么是DIFF

diff算法是一种比照算法。比照两者是旧虚构DOM和新虚构DOM,比照出是哪个虚构节点更改了,找出这个虚构节点,并只更新这个虚构节点所对应的实在节点,而不必更新其余数据没产生扭转的节点,实现精准地更新实在DOM,进而提高效率

其有两个特点:

  • 比拟只会在同层级进行, 不会跨层级比拟
  • 在diff比拟的过程中,循环从两边向两头比拟

DIFF算法的过程:

  • 当数据产生扭转时,订阅者watcher就会调用patch给实在的DOM打补丁
  • 通过isSameVnode进行判断,雷同则调用patchVnode办法
  • patchVnode做了以下操作:

    • 找到对应的实在dom,称为el
    • 如果都有都有文本节点且不相等,将el文本节点设置为Vnode的文本节点
    • 如果oldVnode有子节点而VNode没有,则删除el子节点
    • 如果oldVnode没有子节点而VNode有,则将VNode的子节点实在化后增加到el
    • 如果两者都有子节点,则执行updateChildren函数比拟子节点
  • updateChildren次要做了以下操作:

    • 设置新旧VNode的头尾指针
    • 新旧头尾指针进行比拟,循环向两头聚拢,依据状况调用patchVnode进行patch反复流程、调用createElem创立一个新节点,从哈希表寻找 key统一的VNode 节点再分状况操作

参考 前端进阶面试题具体解答

对于Vue中el,template,render,$mount的渲染

  • 渲染根节点:

    • 先判断有无el属性,有的话间接获取el根节点,没有的话调用$mount去获取根节点。
  • 渲染模板:

    • 有render:这时候优先执行render函数,render优先级 > template。
    • 无render:有template时拿template去解析成render函数的所需的格局,并应用调用render函数渲染。无template时拿el根节点的outerHTML去解析成render函数的所需的格局,并应用调用render函数渲染

渲染的形式:无论什么状况,最初都对立是要应用render函数渲染