vue diff算法与虚拟dom知识整理(11) 书写patch父级新旧为同一节点 子节点与文字交换逻辑实现

news2025/1/18 11:54:09

上文我们简单描述了patch处理同一节点的大体逻辑
这次 我们就来看一下text替换的情况
我们更改案例入口文件 src下的 index.js 代码如下

import h from "./snabbdom/h";
import patch from "./snabbdom/patch";

const container = document.getElementById("container");

const vnode = h("section", {}, [
  h("p", {}, "1A"),
  h("p", {}, "2B"),
  h("p", {}, "3C")
]);

patch( container, vnode)

const btn = document.getElementById("btn");
const vnode1 = h("section", {},"你好");

btn.onclick = function(){
  patch( vnode, vnode1)
}

这里 我们一开始是一个section 里面是三个p标签 更换时 section是文本
我们运行项目
在这里插入图片描述
然后我们点击更改dom按钮
在这里插入图片描述
并没有任何的反应 因为我们还没有写

我们找到patch.js中判断 当新旧节点为同一节点的处理区块
在这里插入图片描述
编写代码如下

//判断  如果 新旧虚拟节点完全相同 则不做操作  直接返回
if(oldVnode === newVnode) return;
/*
    判断新节点的text是不是空的  包括就算text是空字符串  也算有 只要不是undefined未定义
    同时  也要判断  要newVnode没有children  或 children 是个空数组
*/
if(newVnode.text != undefined&&(!newVnode.children||!newVnode.children.length)) {
    //确定一下新旧节点的text文本是不是不同  如果相同就什么都不用做了
    if(newVnode.text !== oldVnode.text) {
        //利用innerText将新节点的text写入到老节点的elm中 因为  elm  存的是真实的dom
        oldVnode.elm.innerText = newVnode.text;
    }
}else{
//否则就算新节点没有text
    
}

在这里插入图片描述
这里 我们编写的逻辑是
首先 我们先用 === 绝对等于 确定新旧节点到底是不是同一个节点 如果是 那就说明都不做了
然后判断 新节点有没有text文本属性
因为 我们这里判断的是 他的text等于undefined 就算是个空字符串都进得来
所以 走到else那就一定是没有 其次 判断了他的子节点字段children如果拿不到或者为空的 才会往里面走
所以 暂时 我们只考虑文本情况 else的逻辑先放着
然后继续往下 我们判断 新旧节点的文本是不是真的不一样 如果一样 我们就不处理了 如果不一样 直接将新节点的text通过innerText写入到旧节点的elm
我们之前也说过 旧节点的 elm 存的就是真实的dom位置
innerText写入的好处在于 它不但会将你的文本写入 他还会干掉之前节点的文本和子节点 也就不需要我们考虑之前有没有子节点了

我们再次运行项目
在这里插入图片描述
然后点击更改dom
在这里插入图片描述
这里 我们的文本就写入成功了

然后 我们再来处理另一种情况
反过来 旧节点上是文字 新节点上带子节点
src下index.js 将 vnode和vnode1 调h的第三个函数换一下就好了
在这里插入图片描述
但这种分两种情况 首先比较简单的是我们现在的情况 老的没有子节点 新的有
还有一种就是 新旧都有子节点 就要继续去递归精细化比较 会非常麻烦
我们先写第一种 老的文本 新的有子节点的情况

来到 patch.js 刚才写的 那个判断新节点有没有text文本和字节的if下
现在我们来写else的代码
在这里插入图片描述
我们在里面这样写

//判断老节点有没有children
if(oldVnode.children&&oldVnode.children.length) {
   //新旧节点都有children的情况 最复杂 先不处理
} else {
   //新的有children  老的没有
   //通过innerHTML 清空老节点中的内容
   oldVnode.elm.innerHTML = "";
   //二者都有children  就算最复杂的情况
   newVnode.children.map(item => {
       let dom = createElement(item);
       oldVnode.elm.appendChild(dom);
   })
}

在这里插入图片描述
这里进来 我们先判断 旧节点有没有 children 如果有 那就麻烦了 需要对新旧两个节点的 children 做比较 我们这里先不管

否则 就是 新的有 children 旧的没有 那么 我们就先用innerHTML将旧节点中无论是内容还是节点 全部干掉
然后循环将新节点的子节点children循环遍历出来 都通过createElement创建成真实的孤儿节点 然后插入到老节点的下方
然后 我们运行项目
在这里插入图片描述
点击更改dom
在这里插入图片描述
可以看到之前的文本就干掉了 新节点也挂上去了

好啦 那么 子节点换文字 和 文字换子节点 甚至你们可以试一下 写到这里文字换文字也可以了
只留了一个最麻烦的 子节点换子节点的逻辑我们后面再继续出文 讲解啦

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/556695.html

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

相关文章

Maven概念及搭建

1.为什么我们要学习 maven? maven 还未出世的时候,我们有很多痛苦的经历 。 痛点 1: jar 包难以寻找 痛点 2: jar 包依赖的问题 痛点 3: jar 不方便管理 痛点 4:项目编译 2.Maven 简介 Maven 是 Apache 软件基金…

Golang中的管道(channel) 、goroutine与channel实现并发、单向管道、select多路复用以及goroutine panic处理

目录 管道(channel) 无缓冲管道 有缓冲管道 需要注意 goroutine与channel实现并发 单向管道 定义单向管道 将双向管道转换为单向管道 单向管道作为函数参数 单向管道的代码示例 select多路复用 案例演示 goroutine panic处理 案例演示 管道…

APP服务端架构的演变

大家好,我是易安! 早期2013年的时候,随着智能设备的普及和移动互联网的发展,移动端逐渐成为用户的新入口,各个电商平台都开始聚焦移动端App,如今经历了10年的发展,很多电商APP早已经没入历史的洪…

日语文法PPT截图31-45

31 形式名词 とき ところ 作为形式名词的话,一般是要写假名不写汉字的 相对时态 如果是一般时/将来时とき,就是先做后面的动作,在做前面的动作。 出教室的时候,关灯。 如果是过去时とき那么,是先做前面的动作&#…

Linux安装elk

稍后补充。 目录 01【安装elk】 es单机 es集群 esHead插件 kibana logstash elastic search:https://www.elastic.co/cn/downloads/elasticsearchlogstash:https://www.elastic.co/cn/downloads/logstashkibana:https://www.elastic.co/cn/downloads/kibana linux下安装E…

vector的介绍

vector的介绍:(vector翻译是向量,但是表示的是顺序表) vector是表示可以改变大小的数组的序列容器。 就像数组一样,vector对其元素使用连续的存储位置,这意味着也可以使用指向其元素的常规指针上的偏移量来访问它们的元素&#xf…

前端代码规范配置

前端代码规范配置 涉及到了eslint、prettier、husky、lint-staged等工具包的使用。 代码规则校验 使用eslint定义代码风格 安装eslint并在.eslintrc.js文件中配置。 npm i eslint -D这个代码风格可以使用公司团队内的规范,如果没有可以在github中找到一些主流的…

主机访问不到虚拟机(centos7)web服务的解决办法

目录 一、背景 二、解决办法 2.1、配置虚拟机防火墙 2.2、修改虚拟机网络编辑器 一、背景 主机可以访问外网,虚拟机使用命令:curl http://网址,可以访问到web服务 ,主机使用http://网址,访问不到虚拟机&#xff08…

TikTok掀动出海淘金潮

嘉晟迪科:在各行各业都已经卷成红海的今天,最稀缺的是什么?当然是增长。那么,增长在哪里?流量在哪里,需求就在哪里,增长也就在那里。 因为短视频风靡全球的流行,内容平台特别是短视频…

Python-web开发学习笔记(2)--- HTML基础

先回顾一下上一篇文章&#xff1a;Python-web开发学习笔记&#xff08;1&#xff09;--- HTML基础_python web开发笔记_尚拙谨言的博客-CSDN博客 中讲了哪几个常用的HTML标签&#xff1a; <head>&#xff1a;头声明 <title>&#xff1a;网页标题 <h1>~<h6…

QT入门看这一篇就够了——超详细讲解(40000多字详细讲解,涵盖qt大量知识)

目录 一、Qt概述 1.1 什么是Qt 1.2 Qt的发展史 1.3 Qt的优势 1.4 Qt版本 1.5 成功案例 二、创建Qt项目 2.1 使用向导创建 2.2 一个最简单的Qt应用程序 2.2.1 main函数中 2.2.2 类头文件 2.3 .pro文件 2.4 命名规范 2.5 QtCreator常用快捷键 三、Qt按钮小程序 …

深度学习实战四:全连接神经网络(基于Pytorch,含数据和详细注释)

文章目录 概念softmax与交叉熵反向传播计算机视觉工具包torchvision全连接神经网络实现多分类概念 神经网络的第一层为输入层,最后一层为输出层,中间的所有层都叫做隐藏层 在计算神经网络层数时,一般不计算输入层,比如: 该神经网络的层数为2。输入层神经元有3个,隐藏层…

redis缓存数据库的使用

一&#xff0c;什么是redis &#xff1f;为什么要用它&#xff1f; 简单介绍&#xff1a; Redis是开源的key-value缓存框架&#xff0c;由c语言编写&#xff0c;也是一款高性能的框架提供多种语言的API 。 SET 每秒11万次 取get每秒81000次。 数据完全存储在内存空间中&…

【C++从0到王者】第八站:模板初阶

文章目录 一、泛型编程二、函数模板1.函数模板概念2.函数模板格式3.函数模板的原理4.函数模板的实例化1.隐式实例化2.显示实例化 5.模板参数的匹配原则 三、类模板1.类模板的格式2.类模板的实例化 一、泛型编程 当我们在写一个交换程序的时候 按照我们之前的想法&#xff0c;我…

谷歌算法快讯0519:近日排名变化频繁,排名或许回温?

从上周末到现在&#xff0c;已经有人注意到排名似乎又有了新的变化&#xff0c;根据WebMaster World上的帖子[1]和业内大家的讨论来看&#xff0c;大家共同的认识是5月16日开始就已经有变化&#xff0c;并且在5月19日的SEMRush Sensor来看已经到达峰值。 有一些在3月份谷歌更新…

yomichan使用笔记

导入词典词典下载 键盘快捷键 Alt Insert 打开搜索页面。 Alt DeleteToggle 打开/关闭扩展。 搜索结果中提供以下快捷方式&#xff1a; Esc取消当前搜索。 Alt PgUpPage 向上浏览结果。 Alt PgDnPage 向下浏览结果。 Alt End 转到最后一个结果。 Alt Home 转到第…

zookeeper的安装使用

zookeeper的安装使用 一、下载安装 https://zookeeper.apache.org/ 点击 download 以我自己的安装为例,linux,3.8.0 准备3台linux服务器&#xff1a;192.168.10.128、192.168.10.129、192.168.10.130 1.上传解压 把apache-zookeeper-3.8.0-bin.tar.gz 上传到 /usr/local/zo…

力扣sql中等篇练习(二十五)

力扣sql中等篇练习(二十五) 1 最繁忙的机场 1.1 题目内容 1.1.1 基本题目信息 1.1.2 示例输入输出 a 示例输入 b 示例输出 1.2 示例sql语句 # Write your MySQL query statement below WITH T as (SELECT t.airport_id,SUM(n) numFROM(SELECT departure_airport airport_i…

【C++进阶之路】内存管理

文章目录 一.内存管理1. 内存布局2. C的内存管理 ①内置类型② 自定义类型 3. operate new 与 operate delete ① 解读operate new源代码② 解读operate delete源代码 4. new和delete的基本原理①new对类对象②delete对类对象 拓展—— 深入理解delete[]和new[]对比 C和C内存…

Java数据类型之字符串

字符集/编码表 ex&#xff1a;ASCII码 字符char&#xff1a;单引号‘ ’引起来的单个字符 转义字符 \n 作用&#xff1a;换行&#xff0c;单引号引用&#xff01;&#xff01;&#xff01; 制表符 \t 作用&#xff1a;加上 \t 前面一共空8个 字符与编码的转换 1.直接输出字…