vDom和domDiff

Posted pengdt

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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,往下看

技术图片

// 列表对比,主要也是根据 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第七篇

以上是关于vDom和domDiff的主要内容,如果未能解决你的问题,请参考以下文章

浅析weex之vdom渲染

为啥 Vue.js 使用 VDOM?

VDOM

手写简易前端框架:vdom 渲染和 jsx 编译

教程篇(7.0) 03. FortiGate基础架构 & 虚拟域(VDOM) ❀ Fortinet 网络安全专家 NSE 4

html vdom()。tag('h1',{},'hello vdom')。toBody()ref:https://qiita.com/tom-u/items/6ab4