当前位置: 首页 > Web前端 > vue.js

vuevirtualdomdiff

时间:2023-04-01 11:03:50 vue.js

虚拟元素节点VNode什么是虚拟元素节点?虚拟元素节点是对真实DOM节点的描述。包含标签名称、标签属性描述对象、子节点集合。//example{tag:'div'props:{key:'uuid',//VNode唯一键,用于新旧VNode差异id:'div',//VNodeid值//...}}virtual优势?无需直接操作dom,虚拟DOM具有批处理和高效的Diff算法,可以减少重排和重绘,提高性能;virtualdom是javascript对象,具有跨平台的优势;virtualdomdiffideaVNodechangetype:REPLACE:当前节点节点替换。比较法:将同一位置的新旧节点一一比较。结构:{type:0,node:newNode}。REORDER:子节点集合中新增和删除的子节点。比较方式:子节点集合兄弟比较。结构:{type:1,moves:[{type:0——delete,index:子节点集合中子节点的下标},{type:1——new,index:子节点在child中node集合中的下标,item:newVNode}]}。PROPS:当前节点属性更改。比较法:将同一位置的新旧节点一一比较。结构:{type:2,props:[{修改propKey:undefined——删除该属性,propKey:newPropValue}]}。TEXT:当前节点文本节点变化。比较法:将同一位置的新旧节点一一比较。结构:{type:3,content:newText}。新旧virtualdomdiff思路总结:由于跨层修改很少见,可以忽略不计,所以只比较同层的子节点集合。注意:对比新旧虚拟dom差异时,采用递归的方式,从上到下统计。比较结果保存在patches[key]中:key是虚拟dom树递归时节点的位置,这样当patch应用到实际的dom树时,才能准确找到对应的节点。先比较newVNodeList和oldVNodeList中同位置(同索引)的VNode,统计VNodeprops,text,VNode被替换(标签名称或VNode唯一键不一致)再比较childVNodeList同级,统计子节点删除,新增情况。并返回一个新数组,其中包含oldVNodeList.length的长度和newVNodeList中VNode/Text的值。使用VNode的唯一键进行比较统计。Applythecomparisonresultpatchestotherealdom注意:在将比较结果patch应用于真实dom时,使用递归的方式,从下往上应用。patch.type===0(替换节点):node.parentNode.replaceChild(newNode,oldNode)patch.type===1(删除,添加子节点):removeChild(removeNode),cloneNode(true),insertBefore(insertNode,beforeNode)patch.type===2(propschange):removeAttribute(prop),setAttribute(prop)patch.type===3(textchange):elementNode.textContent,textNode.nodeValue参考网站:深入分析:如何实现一个VirtualDOM算法:https://github.com/livoras/blog/issues/13同级VNodeList的第一个对比代码:https://github.com/livoras/list-diff/blob/master/lib/diff.js