day185-Diff过程(vuejs)-笔记

要点

  1. patch 函数概览。()
  2. patchVnode 函数概览。
    主要分为两个部分。每个函数中都会有代码并附上代码的行行解释。

    patch() 函数概览

代码 + 解析

代码

/**
* vuejs diff过程
* @param {String} oldVnode
* @param {String} newVnode
*/
function patch(oldVnode, newVnode) {
// 1
if (sameVnode(oldVnode, newVnode)) {
// 2
patchVnode(oldVnode, newVnode)
} else {
// 3
const oEl = oldVnode.el
// 4
let parentEle = api.parentNode(oEl)
// 5
createEle(newVnode)
if (parentEle !== null) {
// 6
api.insertBefore(parentEle, newVnode.el, api.nextSibling(oEl))
api.removeChild(parentEle, oldVnode.el)
oldVnode = null
}
}
// 7
return newVnode
}

解析

  1. 看这两个节点是否值得比较(比比是不是子节点有不一样的地方),比较两者keysel是否完全相等。(sel:节点的选择器)
    vuejs中virtual dom用的是snabbdom,snabbom定义的(Virtual Node属性)[https://github.com/snabbdom/snabbdom#sel--string]有sel、data、children、text、elm、key。这点和React用的库不一样。
  2. 两个节点相互比较
    比较的过程要分好几种情况,后面再记笔记啊。
  3. 进入了不需要比较两个节点的处理流程
    oEl表示节点的父节点。(取父节点做??)
  4. parentEle是父节点的真是dom
  5. 给newVnode创建真实的节点。
  6. 插入新的节点,移除旧节点。(为啥还要特地移除Child,直接把二叉树的顶部根节点移除不就行了?)
  7. 返回newVnode对应的真实dom

patchVnode() 函数概览

代码 + 解析

代码

/**
* 比较不同的节点patchVnode()
* @param {String} oldVnode
* @param {String} newVnode
*/
function patchVnode (oldVnode, newVnode) {
const el = newVnode.el = oldVnode.el
let i, oldCh = oldVnode.children, newCh = newVnode.children
// 这里这个相等应该是深比较吧,完全相等就返回`false`?
// 2.1
if (oldVnode === newVnode) return
// 比较Virtual node中text是否相等?
// 2.2
if (oldVnode.text !== null && newVnode.text !== null && oldVnode.text !== newVnode.text) {
// 如果只是文本内容相等直接替换旧文本内容就行?
api.setTextContent(el, newVnode.text)
} else {
// 2.3
updateEle(el, newVnode, oldVnode)
if (oldCh && newCh && oldCh !== newCh) {
// 2.4
updateChildren(el, oldCh, newCh)
} else if (newCh) {
// 2.5
createEle(newVnode)
} else if (oldCh) {
// 2.6
api.removeChildren(el)
}
}
}

解析

序号2中,什么是值得比较的节点(我理解的是,子节点是不是完全一样?)
比较相同节点sameVnode(oldVnode, newVnode)

2.1 比较引用是否一致,一致则认为没有变化。(引用?)

2.2 文本节点的比较,需要修改则调用Node.textContent = newVnode.text

2.3 判断新旧节点是否存在子节点,新旧节点子节点是不是相等。

2.4 updateChildren函数,是diff核心。

2.5 只有新节点有子节点就调用createEle(newVnode)。在老dom节点上添加子节点。

2.6 只有旧节点有子节点,新节点为空。可以直接遵循新节点。直接删除老节点。

参考

原文点此

文章作者: lmislm
文章链接: http://lmislm.com/2019/07/17/2019-07-17/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 LMISLMのBlog