基于snabbdom的diff算法的学习笔记-03更新节点patchVnode

更新节点patchVnode

更新节点概念

分为一下几种情况:

  1. 新节点是内容是text文字,此时将旧节点的内容更新为文字(无论旧DOM的子节点是何种形式,因为本笔记不考虑混合情况)
  2. 新节点是内容是h函数,此时将节点的h函数创建为真实DOM并替换旧DOM的子节点。
  3. 新节点是Array,此时需要分类讨论
    • 若旧节点是文字或者h函数,①清空老节点 ②将Array依次创建为DOM并插入老DOM
    • 若旧节点也是Array,此时我们需要实现最小化更新,及:找到子节点中相同的节点更新节点并将节点对应的DOM放至到更新后的位置,删除不要的节点,新增新增的节点,也就是我们所说的diff算法。
  4. 更新结束之后将最新的DOM指向新vnode的elm

更新节点语法

// patchVnode
import createElement from "./createElement"
// 最小化更新函数,下一篇介绍
import updateChildren from "./updateChildren"

// 移除所有子节点
function removeAllChildren(element) {
    while (element.firstChild) {
        element.removeChild(element.firstChild);
    }
}

export default function patchVnode(oldVnode, newVnode) {
    // 内存中是同一节点
    if (oldVnode === newVnode) return
    // 判断新vnode有没有text属性
    if (newVnode.text && (newVnode.children === undefined || newVnode.children.length === 0)) {
        // 新vnode有且仅有text属性
        if (newVnode.text !== oldVnode.text) {
            oldVnode.elm.innerText = newVnode.text
        }
    } 
    else if (newVnode.children && !Array.isArray(newVnode.children)) {
        // 新节点是h函数
        let dom = createElement(newVnode.children)
        removeAllChildren(oldVnode.elm)
        oldVnode.elm.appendChild(dom)
    }
    else if (newVnode.children && Array.isArray(newVnode.children) && newVnode.children.length > 0) {
        // 新节点有且仅有非文字子节点
        // 判断老节点类型
        if (oldVnode.children && oldVnode.children.length > 0) {
            // 老节点是数组->最小化更新,下一篇具体描述
            updateChildren(oldVnode.elm, oldVnode.children, newVnode.children)
        } else {
            // 老节点是文字orvnode
           removeAllChildren(oldVnode.elm)
            for (let i = 0; i < newVnode.children.length; i++) {
                let dom = createElement(newVnode.children[i])
                oldVnode.elm.appendChild(dom)
            }
        }
    } 
    newVnode.elm = oldVnode.elm
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值