虚拟DOM与diff算法
- snabbdom
- 虚拟DOM
- diff算法
snabbdom
- 是什么:snabbdom是著名的虚拟DOM库,是diff算法的鼻祖,Vue源码借鉴了snabbdom
虚拟DOM
-
是什么:本质上是存在内存里的 JavaScript 对象
-
作用:用来描述真实DOM的层次结构,真实DOM上的一切属性都能在虚拟DOM上找到对应的属性,并且diff算法也是作用在虚拟DOM上的
-
怎么用(如何产生):用h函数可以生成虚拟DOM
// 调用h函数 h('p', {}, 'aaa'); // 得到以下的虚拟DOM { "sel": "p", "data": {}, "text": "aaa" } // 真实DOM如下 <p>aaa</p>
-
h函数代码如下
import vnode from "./vnode"; // 低配版h函数,必须接受三个参数(生成vnode) // 形态如下: /* ① h('div', {}, '文字') ② h('div', {}, []) ③ h('div', {}, h('div', {}, '文字')) */ export default function (sel, data, c) { if (arguments.length !== 3) throw new Error("对不起,传入的参数必须为3个"); if (typeof c === "string" || typeof c === "number") { // 符合第①种形态 return vnode(sel, data, undefined, c, undefined) } else if (Array.isArray(c)) { // 符合第②种形态 let children = []; for (let index = 0; index < c.length; index++) { const element = c[index]; // 如果不是h() if ( !(typeof element === "object" && element.hasOwnProperty("sel")) ) { throw new Error("对不起,传入的参数有误"); } children.push(element); } return vnode(sel, data, children, undefined, undefined); } else if (typeof c === "object" && c.hasOwnProperty("sel")) { // 符合第③种形态 let children = [c] return vnode(sel, data, children, undefined, undefined); } else { throw new Error("对不起,传入的参数有误"); } // return vnode(sel, data, children, undefined, undefined); }
-
diff算法
-
是什么:一种作用于虚拟DOM上的算法
-
作用:通过在虚拟DOM上进行精细化比较,从而达到最小量更新真实DOM的效果
-
diff算法是怎么做的
-
diff算法只在同一层进行比较,不同层的话会直接暴力删除旧的,插入新的
-
diff算法对同一个虚拟节点进行精细化比较,也就是选择器和key相同的虚拟节点。
-
diff算法的比较如下图
-