vDom and domDiff

Virtual dom and 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)

The difficulty lies in comparing diff
give you two arrays, arrays filled with several objects, compare the difference between these two arrays, you first need to consider what is == order, that is, reusability ==, because there are sub-dom elements, then if we can move the location, on the priority moving position, contrast, do not have to delete, in the new add on the line, however, but the contrast target cost is very high, I want to compare two objects is not the same to contrast name, comparison of age, comparing a lot of value in order to know if this is the original first value is now changed to the third, how to reduce the contrast with key, do comparison with the amount of objects in the same, because there are key, so Object-level comparison becomes a comparison string array level, this is one of the optimization program vue, how to compare diff string array, look down

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 }
}

Update
the new add, delete, delete, and move the first move, and then compared changes in the value of the tag data movement, such as changes in the value of class changes, changes in content and so on, after which they performed recursively a child changes in level, in order to complete a domDiff

Idealized
says only idealized contrast, if I do not set the key, vue will set up their own, such as vue on the dom on a special id, it vue can also set up their own set us what he needs to generate a set id uuid and the like, is a cost

References
domDiff first post
domDiff The second
domDiff Title III
domDiff Title IV
domDiff fifth chapter
domDiff Title VI
domDiff VII

Guess you like

Origin www.cnblogs.com/pengdt/p/12072473.html