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函数渲染