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

news2024/12/24 9:06:21

上文
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.coloradmin.cn/o/615172.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Scrapy ImagesPipeline下载图片

一、 ImagesPipeline是啥 ImagesPipeline是scrapy自带的类&#xff0c;用来处理图片(爬取时将图片下载到本地)。 二、ImagesPipeline优势&#xff1a; 将下载图片转换成通用的jpg和rgb格式避免重复下载缩略图生成图片大小过滤异步下载 三、ImagesPipeline工作流程 爬取一个…

Echarts构建指定省份的地图

1. 自行准备好Echarts环境 Echarts官网&#xff1a;https://echarts.apache.org/zh/index.html 2. 下载需要的省份或者城市的json地理信息文件 下载我们需要显示地区的Json数据&#xff0c;这个Json数据用于Echart的地图显示 例如我这里是下载的&#xff1a;湖南、湖北、四川…

同步模式之顺序控制线程执行

tip: 作为程序员一定学习编程之道&#xff0c;一定要对代码的编写有追求&#xff0c;不能实现就完事了。我们应该让自己写的代码更加优雅&#xff0c;即使这会费时费力。 文章目录 一、同步模式之顺序控制线程执行二、代码样例三、三个线程分别输出a、b、c&#xff0c;按顺序输…

作为一个项目管理成员,怎样才能有效监控项目执行?

作为一个项目管理成员&#xff0c;有效监控项目执行是确保项目成功的关键。在项目执行期间&#xff0c;您需要密切关注项目进展&#xff0c;并及时采取行动来纠正任何偏差。以下是几个有效的方法&#xff0c;可以帮助您监控项目执行并确保项目按计划顺利进行。 1. 制定详细的项…

C语言进阶--数据的存储

目录 数据类型介绍 基本内置类型&#xff1a; 类型的意义&#xff1a; 类型的基本归纳&#xff1a; 整型在内存中的存储 原码&#xff0c;反码和补码&#xff1a; 大小端存储模式&#xff1a; 大小端产生原因&#xff1a; 浮点型在内存中的存储 数据类型介绍 基本内…

六、机械手的种类

机械手是机器人能够完成指令的一个重要输出装置&#xff0c;机器臂是否合理、有效&#xff0c;决定了机 器人能否发挥出应有的作用。 机械手是一种能模仿人手和臂的某些动作功能&#xff0c;用以按固定程序抓取、搬运物件或操作工具的自动操作装置。特点是可以通过编程来完成各…

wy的leetcode刷题记录_Day68

wy的leetcode刷题记录_Day68 声明 本文章的所有题目信息都来源于leetcode 如有侵权请联系我删掉! 时间&#xff1a;2023-6-6 前言 目录 wy的leetcode刷题记录_Day68声明前言1019. 链表中的下一个更大节点题目介绍思路代码收获 1019. 链表中的下一个更大节点 2352. 相等行列…

CPU、内存、缓存的关系

术语解释 &#xff08;1&#xff09;CPU&#xff08;Central Processing Unit&#xff09; 中央处理器 &#xff08;2&#xff09;内存 内存用于暂时存放CPU中的运算数据&#xff0c;以及与硬盘等外部存储器交换的数据。它是外存与CPU进行沟通的桥梁&#xff0c;内存的运行决定…

Docker容器管理

docker容器相当于一个进程&#xff0c;性能接近于原生&#xff0c;几乎没有损耗&#xff1b; docker容器在单台主机上支持的数量成百上千&#xff1b; 容器与容器之间相互隔离&#xff1b; 镜像是创建容器的基础&#xff0c;可以理解镜像为一个压缩包 docker容器的管理 容…

深耕电力行业,百度智能云助力电厂节煤降耗

山西省吕梁市汾阳市三泉镇&#xff0c;晋能集团旗下山西国峰煤电有限责任公司的两台300MW循环流化床直接空冷机组正在运行&#xff0c;燃煤通过传送带进入锅炉燃烧&#xff0c;将水加热成高温高压蒸汽&#xff0c;用以推动汽轮机拖动发电机旋转发电&#xff0c;支撑工业生产、点…

CW32-Template CW32F030开发板工程模板

国产MCU Embedded-CW32-Board-Template Embedded-CW32-Board-Template CW32-Template第三方资源集合 CW-Template CW32开发者开发板资料 CW32-Board 开发板资料 合集 官方提供的案例Examples CW32F030_StandardPeripheralLib\Examples CW32-48F大学计划板例程 EX1流…

优思学院|精益和六西格玛都强调的一件东西...

精益和六西格玛有着诸多不同&#xff0c;它们的方法和理念也不尽相同&#xff0c;但却有一件东西&#xff0c;是他们的共同理念和工具&#xff0c;那就是----标准。 标准&#xff0c;是企业管理中至关重要的一环。标准&#xff0c;不仅指导着我们对人、物和流程的处理方式&…

2023年鄂州中级职称水测考试什么时候考试?

今天鄂州中级职称水测考试开始打印准考证了&#xff0c;但是只能打印部分专业的水测准考证&#xff0c;按照专业&#xff0c;按照批次打印的。 具体通知如下: 各位考生&#xff1a; 为积极稳妥做好我市晋升中、初级专业技术职称综合系列水平能力测试工作&#xff0c;现按专业分…

【2023 年第十三届 MathorCup 高校数学建模挑战赛】A 题 量子计算机在信用评分卡组合优化中的应用 37页论文及代码

相关信息 &#xff08;1&#xff09;建模思路 【2023 年第十三届 MathorCup 高校数学建模挑战赛】A 题 量子计算机在信用评分卡组合优化中的应用 详细建模过程解析及代码实现 【2023 年第十三届 MathorCup 高校数学建模挑战赛】 B 题 城市轨道交通列车时刻表优化问题 详细建…

2023BR软件、Adobe Bridge下载、安装教程

最后附下载地址 Adobe Bridge CS5 软件是一款功能强大的媒体管理器&#xff0c;它允许您集中访问所有创作资源。 功能介绍 1、可以方便地访问本地PSD、AI、INDD 和 Adobe PDF 文件以及其它 Adobe 和非 Adobe 应用程序文件。 2、可以将资源按照需要拖移到版面中进行预览&…

安卓平台下的即时通讯技术深入解析【实时聊天应用开发实战】

摘要: 本文将详细介绍如何使用安卓开发技术实现一个实时聊天应用。我们将通过构建一个基于安卓平台的聊天应用,演示如何处理用户注册、登录、消息发送和接收等关键功能。文章将涵盖安卓开发的各个方面,包括用户界面设计、后端服务器搭建、网络通信、数据存储和安全性等。读…

spring6

Spring6 1、概述 1.1、Spring是什么&#xff1f; Spring 是一款主流的 Java EE 轻量级开源框架 &#xff0c;Spring 由“Spring 之父”Rod Johnson 提出并创立&#xff0c;其目的是用于简化 Java 企业级应用的开发难度和开发周期。Spring的用途不仅限于服务器端的 开发。从简…

【Mysql数据库从0到1】-入门基础篇--数据库了解

【Mysql数据库从0到1】-入门基础篇--数据库了解 &#x1f53b;一、数据库产生背景&#x1f53b;二、数据库有关概述&#x1f53b;三、数据库访问接口&#x1f53b;四、数据库种类&#x1f53b;五、数据库有关术语&#x1f53b;六、常见DBMS排名&#x1f53b;七、常见数据库介绍…

(三)PUN 2核心内容(待更新)

一、实例化 大多数多人游戏需要创建和同步一些游戏对象。也许它是一个角色、一些单位或怪物&#xff0c;应该出现在房间内的所有客户端上。 PUN 提供了一种方便的方法来做到这一点。 与 Unity 中一样&#xff0c;Instantiate 和 Destroy 用于管理 GameObjects 的生命周期。 PU…

令人惊艳的高效算法盘点(附示例)

令人惊艳的高效算法盘点&#xff08;附示例&#xff09; 在计算机科学领域&#xff0c;算法是解决问题的基石。有些算法&#xff0c;因为其高效性和惊人表现&#xff0c;令人瞩目。本文将为你介绍一些令人惊艳的高效算法&#xff0c;让我们一起来领略这些算法的魅力吧&#xf…