virtual DOM and life circle of Vue.js

1. virtual DOM

一个真正的dom节点可以在js中映射成一个这样的对象,也就是js中的虚拟dom。

const node={
  tag: 'ul',
  attributes: {
    id: 'list1',
    class: ['classname1', classname2'],
    ...
    },
  chirldren: [child1, child2, child3,...]
}

我们在创建一个vue实例之后,它会先被render function渲染成虚拟dom,然后再mount到真正dom上。

1.1 .el

vue实例的el可以是一个string字符串或者是一个HTMLElement.

1.2 virtual dom -- diff

function patch (oldVnode, Vnode){
if (sameVnode(oldVnode,Vnode) {
   patchVnode(oldVnode, Vnode)
  } else {
        const oEl = oldVnode.el
        let parentEle = api.parentNode(oEl)
        createEle(vnode)
        if (parentEle !== null) {
            api.insertBefore(parentEle, vnode.el, api.nextSibling(oEl))
            api.removeChild(parentEle, oldVnode.el)
            oldVnode = null
        }
  }
}

sameVnode的函数返回结果如果为true,表示dom元素可以复用;如果为false,则会生成新的dom元素,替换原来的dom元素。在dom元素可以复用的情况下,会进入patchVnode函数:

patchVnode (oldVnode, vnode) {
    const el = vnode.el = oldVnode.el
    let i, oldCh = oldVnode.children, ch = vnode.children
    if (oldVnode === vnode) return
    if (oldVnode.text !== null && vnode.text !== null && oldVnode.text !== vnode.text) {
        api.setTextContent(el, vnode.text)
    }else {
        updateEle(el, vnode, oldVnode)
        if (oldCh && ch && oldCh !== ch) {
            updateChildren(el, oldCh, ch)
        }else if (ch){
            createEle(vnode) //create el's children dom
        }else if (oldCh){
            api.removeChildren(el)
        }
    }
}

updateEle,更新孩子节点是diff算法中最核心的部分。
下图中,菱形表示Vnode对象,圆形表示真实dom元素。下图中可以看到,当新旧children数目相同的时候,只需要patch即可。

新旧children的patch

未完待续……
8个生命周期函数

Reference
http://hcysun.me/vue-design/zh/renderer-diff.html

你可能感兴趣的:(virtual DOM and life circle of Vue.js)