vDom和domDiff

虚拟dom和domDiff

1. 构建虚拟DOM
var tree = el('div', {'id': 'container'}, [
    el('h1', {style: 'color: blue'}, ['simple virtal dom']),
    el('p', ['Hello, virtual-dom']),
    el('ul', [el('li')])
])

2. 通过虚拟DOM构建真正的DOM
var root = tree.render()
document.body.appendChild(root)

3. 当数据发生变化,生成新的虚拟DOM
var newTree = el('div', {'id': 'container'}, [
    el('h1', {style: 'color: red'}, ['simple virtal dom']),
    el('p', ['Hello, virtual-dom']),
    el('ul', [el('li'), el('li')])
])

4. 比较两棵虚拟DOM树的不同
var patches = diff(tree, newTree)

5. 在真正的DOM元素上应用变更
patch(root, patches)

难点就在于比较diff
给你两个数组,数组里装着几个对象,对比这两个数组的区别,首先需要考虑的是什么,顺序,也就是复用性,因为dom里有子元素,如果能移动位置,就优先移动位置,对比之后,没有的就删了,在把新的添加就行,但是,但是对比对象的成本非常的高,我要对比两个对象是不是同一个要对比name,对比age,对比很多的值,才能知道这个是原本的第一个值现在变到第三个了,如何减少对比,用key,用对象里不变的量做对比,因为有key,所以对象级别的对比就变成了字符串数组级别的对比,这也是vue的优化方案之一,如何对比字符串数组的diff,往下看

image.png

// 列表对比,主要也是根据 key 值查找匹配项
// 对比出新旧列表的新增/删除/移动
function diffList(oldList, newList, index, pathchs) {
    let change = []
    let list = []
    const newKeys = getKey(newList)
    oldList.map(v => {
	 if (newKeys.indexOf(v.key) > -1) {
		 list.push(v.key)
	 } else {
		 list.push(null)
	 }
    })
    // 标记删除
    for (let i = list.length - 1; i>= 0; i--) {
	 if (!list[i]) {
	    list.splice(i, 1)
	    change.push({ type: 'remove', index: i })
	 }
    }
    // 标记新增和移动
    newList.map((item, i) => {
	 const key = item.key
	 const index = list.indexOf(key)
	 if (index === -1 || key == null) {
		 // 新增
		 change.push({ type: 'add', node: item, index: i })
		 list.splice(i, 0, key)
	 } else {
		 // 移动
		 if (index !== i) {
			 change.push({
				 type: 'move',
				 form: index,
				 to: i,
			 })
			 move(list, index, i)
		 }
	 }
    })
    return { change, list }
}

更新
新增的新增,删除的删除的,移动的先移动,再对比移动的数据的标签值的变化,比如值的变化,class的变化,内容的变化等等,之后还要递归执行子一级的变化,才能完成一次domDiff

理想化
上面说的只是理想化的对比,如果我不设置key呢,vue会自己设置,就比如vue的dom上个特殊的id,那vue能自己设置还要我们设置干什么,他设置需要去生成uuid之类的id,是需要成本的

参考资料
domDiff第一篇
domDiff第二篇
domDiff第三篇
domDiff第四篇
domDiff第五篇
domDiff第六篇
domDiff第七篇

原文地址:https://www.cnblogs.com/pengdt/p/12072473.html