vue diff算法与虚拟dom知识整理(14) patchVNode处理子节点新增和删减

news/2024/11/29 8:02:44/

上文
vue diff算法与虚拟dom知识整理(13) 手写patch子节点更新换位策略
我们实现了子节点位置的更新策略
但还有一些匹配不到的情况会导致死循环 那么我们继续来优化一下

我们先将src下的 index.js
代码改成这样

import h from "./snabbdom/h";
import patch from "./snabbdom/patch";const container = document.getElementById("container");const vnode = h("section", {}, [h("p", {key:"a"}, "a"),h("p", {key:"b"}, "b"),h("p", {key:"c"}, "c")
]);patch( container, vnode)const btn = document.getElementById("btn");
const vnode1 = h("section", {},[h("p", {key:"a"}, "a"),h("p", {key:"b"}, "b"),h("p", {key:"c"}, "c"),h("p", {key:"d"}, "d")
]);btn.onclick = function(){patch( vnode, vnode1)
}

我们先来处理 在后面多加入一个节点的逻辑
首先 我们这样写 现在肯定是没有效果的 因为我们并没有写新增的逻辑

我们打开案例中的updateChildren.js
在最上面引入一下createElement

import createElement from "./createElement";

然后 我们在 updateChildren.js 的最后面 加入这段代码

//查看是否还有剩余节点
//判断处理后  新前是否还是比新后小或者二者相同
if (newStartIdx <= newEndIdx) {//定义before 复制微新后节点  如果拿不到新后 就直接赋值为unll  因为  insertBefore第二个标杆节点参数给null他就会将节点插入在最后面const before = newCh[newEndIdx + 1] == null ? null : newCh[newEndIdx + 1].elm;//开启循环 i等于没做完的新前节点  只要i还小于或者等于新后旧继续循环for(let i = newStartIdx ; i <= newEndIdx; i++) {//用createElement将  newCh(新虚拟节点的集合) 的第i个下标从虚拟节点准成真的个人节点  并插入在before节点的前面parentElm.insertBefore(createElement(newCh[i]),before);}
}

加到 while 循环的后面
在这里插入图片描述
我们简单判断 如果循环都已经结束了 如果新前还没有加到比新后大 说明 我们的新节点的子节点并没有处理完
我们先获取新后节点
然后 循环遍历 将剩余的新节点都插入到新后后面去
这里 写了个三元运算符 当新后拿不到是 赋值为unll 意思就是 利用了insertBefore第二个参数 如果是unll就自动将元素插在最后面的特性
还有就是createElement 因为 你现在遍历的是虚拟节点 所以 要通过createElement 将虚拟节点变为孤儿节点 然后 插入到dom后面

然后 我们运行项目
在这里插入图片描述
点击更改dom 会发现 我们的d节点就上去了
在这里插入图片描述
但是 如果现在 我们旧节点 如果大于新节点

例如 旧节点的 子节点为 a b c d 新节点 为 a b c 不用试了 我已经帮你们试过了 功能肯定是实现不了的

我们接下来 来处理一下删除的操作
我们先将src下的index.js入口文件改成这样

import h from "./snabbdom/h";
import patch from "./snabbdom/patch";const container = document.getElementById("container");const vnode = h("section", {}, [h("p", {key:"a"}, "a"),h("p", {key:"b"}, "b"),h("p", {key:"c"}, "c"),h("p", {key:"d"}, "d"),h("p", {key:"e"}, "e")
]);patch( container, vnode)const btn = document.getElementById("btn");
const vnode1 = h("section", {},[h("p", {key:"a"}, "a"),h("p", {key:"b"}, "b"),h("p", {key:"c"}, "c"),h("p", {key:"e"}, "e")
]);btn.onclick = function(){patch( vnode, vnode1)
}

暂时 我们点击肯定是没有什么效果的 因为 我们并没有处理对旧节点进行删除的操作
多出来的旧子节点就还没有得到处理

然后 我们将 updateChildren.js 新增的判断

if (newStartIdx <= newEndIdx) {

下面加一个else if
参考代码如下

//判断旧前还是小于或等于旧后  说明旧节点有多余部分
}else if(oldStartIdx <= oldEndIdx) {//定义一个i 接受旧前的值  一直循环到他比旧后大位置  即处理旧前到旧后之间多出来的节点for (let i = oldStartIdx; i <= oldEndIdx; i++){//将多余部分从dom中删除parentElm.removeChild(oldch[i].elm);}
}

在这里插入图片描述
这样 我们继续去判断 旧前和旧后 如果旧前没有大于旧后 说明还有节点没处理 即 旧节点有多余的节点
我们直接循环调用removeChild给他们都干掉

这样 我们再运行代码
在这里插入图片描述
点击更改dom
在这里插入图片描述
可以看到 这里这个d就被干掉了

但是目前就还有一个问题
例如 我们将src下的index.js代码修改如下

import h from "./snabbdom/h";
import patch from "./snabbdom/patch";const container = document.getElementById("container");const vnode = h("section", {}, [h("p", {key:"a"}, "a"),h("p", {key:"b"}, "b"),h("p", {key:"c"}, "c"),h("p", {key:"d"}, "d")
]);patch( container, vnode)const btn = document.getElementById("btn");
const vnode1 = h("section", {},[h("p", {key:"a"}, "a"),h("p", {key:"b"}, "b"),h("p", {key:"c"}, "c"),h("p", {key:"e"}, "e")
]);btn.onclick = function(){patch( vnode, vnode1)
}

这样运行 你会发现 不但没效果 而且还死循环了
这就是因为旧后和新后没有命中到
这个问题我们后续继续解决


http://www.ppmy.cn/news/185557.html

相关文章

简谈软件版本周期 | Alpha、Beta、RC、Stable版本之间的区别

目录 &#x1f48c; 引言 ⭕ 软件版本周期 &#x1f6e0;️ 软件开发期 ⚖️ 软件完成期 &#x1f4b0; 商业软件版本 &#x1f48c; 引言 定义好版本号&#xff0c;对于产品的版本发布与持续更新很重要&#xff1b;但是对于版本怎么定义&#xff0c;规则如何确定&#x…

运动型蓝牙耳机怎么选,目前值得拥有的五款耳机推荐

在绝大多数人生活中&#xff0c;生活都离不开音乐。在隐约间运动跟音乐已经产生了一些不可分割的联系&#xff0c;有不少的网友习惯了戴着运动耳机听音乐&#xff0c;音乐能让我们享受生活&#xff0c;提高我们对于运动的积极性。那么我们又该怎么样去选择合适自己的运动耳机&a…

运动耳机排行榜前十名,六款目前最好的运动耳机推荐

我们在进行一些运动项目的时候会不会觉得枯燥没动力&#xff1f;相信在这种情况下&#xff0c;绝大多数小伙伴都会选择听音乐&#xff0c;音乐可以解决运动过程中带来的枯燥、无聊的情况&#xff0c;也能刺激我们的大脑&#xff0c;让我们运动起来更有劲&#xff0c;而且运动时…

【读书笔记@观点】正确的认识论

【读书&笔记观点】正确的认识论 &#x1f4da;认识事物有一个过程&#xff0c;这个过程分为两个阶段&#xff1a;1、感性认识&#xff1b;2、理性认识。 初次遇见一个人&#xff0c;初次拿起一本厚厚、概念纷繁复杂的书本的时候&#xff0c;你对对方的的印象、认识、对书本…

运动耳机怎么选,盘点目前适合运动的几款耳机

​相对于传统耳机而言&#xff0c;现如今越来越多的人喜欢使用骨传导耳机&#xff0c;毕竟无需入耳不管是在运动还是日常&#xff0c;防丢能力会更加好&#xff0c;耳挂式的佩戴更加不用担心在剧烈运动的情况下脱落&#xff0c;但在骨传导耳机中已经有了很多个品牌入驻&#xf…

值得入手的运动耳机有哪些、值得推荐的运动耳机

现如今大家都在提倡健康运动生活&#xff0c;因此也衍生出来了很多的运动装备。不少喜欢户外运动的人,都喜欢佩戴运动耳机。但是,在运动的过程中,如果耳机出现脱落、进水、电量不足等问题,对运动者来说,也是一件非常影响运动情绪的事情。拥有一款好的运动耳机装备能够大幅度提升…

运动耳机排行榜10强,推荐其中六款好用的运动耳机

随着人们的健康观念越来越强&#xff0c;很多人都会抽出时间进行运动。但是单纯的运动本身是挺乏味的&#xff0c;这时候大家都会选择带上耳机&#xff0c;在运动的同时享受音乐带来的乐趣。市面上也随之出现了琳琅满目的运动耳机&#xff0c;大家要选择的时候往往都要纠结很久…

性价比高的运动蓝牙耳机推荐,分享几款值得入手的运动耳机

对于一位运动爱好者来说&#xff0c;在运动的时候佩戴着一款耳机听听歌&#xff0c;还是个很不错的选择&#xff0c;释放压力的同时还能给我们运动带来动力&#xff0c;非常nine。对于喜欢运动的用户群体&#xff0c;在对运动耳机方面要求也高&#xff0c;一副好用得运动耳机&a…