虚拟dom及diff算法之 —— h函数和diff函数

新虚拟dom和老虚拟dom进行diff算法(精细化比较),算出如何最小量更新,最后反映到真实dom上

diff是发生在虚拟dom上的

模板编译

虚拟dom如何产生 - 渲染函数(h函数)

h函数产生虚拟节点(vnode)

Dom节点:<a href="https://www.baidu.com">真实Dom</a>
调用h函数:h('a',{props:{href:"https://www.baidu.com"}},'真实Dom')
生成虚拟节点:{"sel":"a","data":{props:{href="https://www.baidu.com"}},"text:"真实Dom"}

虚拟节点有哪些属性

{children:{}, // 子元素data:{}, // 属性,样式elm:undefined, // 这个元素真正的dom节点,如果是undefined证明这个虚拟dom还没有上树key:undefined, // 节点唯一标识sel:"div", // 选择器text:"真实Dom" // 文字
}

使用patch函数让虚拟节点上树,一个容器只能让一个虚拟dom上树,除非h函数进行嵌套

import { init, classModule, propsModule, styleModule, eventListenersModule, h } from 'snabbdom'
// 创建patch函数
const patch = init([classModule, propsModule, styleModule, eventListenersModule])
// 创建虚拟节点
var myVnode1 = h('a', { props: { href: 'https://www.baidu.com', target: '_blank' } }, '真实Dom')
// 使用patch函数让虚拟节点上树
const container = document.getElementById('container')
// 一个容器只能让一个虚拟dom上树,除非h函数进行嵌套
patch(container, myVnode2)

h函数可以嵌套使用创建虚拟dom树

var myVnode3 = h('ul', {}, [h('li', '苹果'), h('li', '西瓜'), h('li', '香蕉'), h('li', '火龙果')])

第二个参数写不写不影响

var myVnode21 = h('div', {}, '我是一个盒子')
var myVnode22 = h('div', '我是一个盒子')

第三个参数如果再有一个子元素可以不要数组,如果有多个子元素需要使用数组

var myVnode3 = h('ul', {}, [h('li', {}, '苹果'),h('li', '西瓜'),h('li', [h('div', [h('p', '嘻嘻'), h('p', '哈哈')])]),h('li', h('span', '榴莲'))
])

h函数的重载(h函数的实现形式)

h('div')
h('div','文字'),
h('div',[])
h('div',h())
h('div',{},'文字'),
h('div',{},[])
h('div',{},h())

vnode函数

// 函数目的:将5个参数组合成一个对象返回
export default function (sel, data, children, text, elm) {return { sel, data, children, text, elm }
}

h函数的实现

import vnode from './vnode'
// 弱重载:函数重载功能没有实现,必须接收3个参数
// 形态1:h('div',{},'文字')
// 形态2:h('div',{},[])
// 形态3:h('div',{},h())
export default function (sel, data, c) {// 检查参数个数if (arguments.length !== 3) throw new Error('低配版,必须传入3个参数')// 检查参数c的类型if (typeof c === 'string' || typeof c === 'number') {// 形态1的h函数:文字return vnode(sel, data, undefined, c, undefined)} else if (Array.isArray(c)) {// 形态2的h函数:数组let children = []// 遍历c,收集childrenfor (let i = 0; i < c.length; i++) {// c[i]必须是一个有sel属性的对象if (!(typeof c[i] === 'object' && c[i].hasOwnProperty('sel'))) throw new Error('传入的数组有项不是h函数')// 不用执行c[i],因为在调用h函数的时候已经执行了children.push(c[i])}// 循环结束,锁门children收集完毕了,可以返回带有children属性的虚拟节点了return vnode(sel, data, children, undefined, undefined)} else if (typeof c === 'object' && c.hasOwnProperty('sel')) {// 形态3的h函数:h函数(一个有sel属性的对象),即的唯一的childrenlet children = [c]return vnode(sel, data, children, undefined, undefined)} else {throw new Error('传入的第三个参数不对')}
}

请添加图片描述

请添加图片描述

diff算法原理

最小量更新:key很重要,key是这个节点的唯一标识,告诉diff算法,在更改前后他们是同一个dom节点

只有是同一个虚拟dom节点,才能进行精细化比较,否则会暴力删除旧的,插入新的
如果定义是同一个虚拟节点:选择器和key都相同

只进行同层比较,不会进行跨层比较,而是暴力删除旧的,插入新的

diff不是那么无微不至,但是2,3在实际的vue开发中,基本不会遇见

请添加图片描述

创建节点时,所有子节点都是需要递归创建的

手写第一次上树时

虚拟dom如何通过diff变成真正的dom

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux: MV指令(覆盖替换重命名)

MV指令 mv [-bfiuv] [–help] [–version] [-S <附加字尾>] [-V <方法>] [源文件或目录] [目标文件或目录]-b 若需覆盖文件&#xff0c;则覆盖前先行备份-f 若目标文件或目录与现有的文件或目录重复&#xff0c;则直接覆盖现有的文件或目录-i 覆盖前先行询问用户–…

【LeetCode刷题-队列】--2073.买票需要的时间

2073.买票需要的时间 方法一&#xff1a;使用队列 class Solution {public int timeRequiredToBuy(int[] tickets, int k) {Queue<TicketBuyer> queue new LinkedList<>();for(int i 0;i<tickets.length;i){TicketBuyer buyer new TicketBuyer();buyer.inde…

快速了解推荐引擎检索技术

目录 一、推荐引擎和其检索技术 二、推荐引擎的整体架构和工作过程 &#xff08;一&#xff09;用户画像 &#xff08;二&#xff09;文章画像 &#xff08;三&#xff09;推荐算法召回 三、基于内容的召回 &#xff08;一&#xff09;召回算法 &#xff08;二&#xf…

linux基础学习

迷茫不可怕&#xff0c;说明你还在向前走 失败不可怕&#xff0c;只要你还能爬起来 ​​​​​​​ 目录 ​编辑 为什么要学习linux操作系统&#xff1f; linux系统的安装 FinalShell 虚拟机快照 第二章 基本知识 linux目录结构 linux路径的描述方式 linux命令入门…

【C语言进阶】之动态内存管理笔试题及柔性数组

【C语言进阶】之动态内存管理笔试题 1.动态内存管理笔试题汇总1.1第一道题1.2第二道题1.3第三道题1.4第四道题 2.C/C内存管理3.柔性数组3.1什么是柔性数组3.2柔性数组的使用3.2柔性数组的优点 &#x1f4c3;博客主页&#xff1a; 小镇敲码人 &#x1f680; 欢迎关注&#xff1a…

【已解决】设置SSH主机:VS Code-正在本地下载 VS Code 服务器

问题描述 很简单&#xff0c;就是我电脑强制重启之后用vscode再去连服务器&#xff0c;发现连不上了 解决办法 如上图&#xff0c;点击重试按钮&#xff0c;下面的这些东西就可以复制粘贴了 ctrf查找commit&#xff0c;这个时候就能找到一串d037ac076cee195194f93ce6fe2bdfe296…

Spring Security OAuth 2.0 资源服务器— JWT

目录 一、JWT的最小依赖 二、JWT的最基本配置 1、指定授权服务器 2、初始预期&#xff08;Startup Expectations&#xff09; 3、运行时预期&#xff08;Runtime Expectations&#xff09; 三、JWT认证是如何工作的 四、直接指定授权服务器 JWK Set Uri 五、提供 audie…

中国联通携手华为助力长城精工启动商用5G-A柔性产线

[中国&#xff0c;河北&#xff0c;2023年11月3日] 近日&#xff0c;中国联通携手华为助力精诚工科汽车系统有限公司保定自动化技术分公司&#xff08;简称长城精工自动化&#xff09;启动5G-A超高可靠性超低时延柔性产线的商用阶段。 在河北保定精工自动化工厂&#xff0c;5G…

Java医院HIS系统源码

Java医院HIS系统源码 项目描述 该项目是用springbootlayuishiro写的医院管理系统&#xff0c;该系统的业务比较复杂&#xff0c;数据库一共有36张表。项目的视频业务参考文档&#xff0c;都在百度云盘中。可以先看看视频和参考文档。 运行环境 jdk8mysqlIntelliJ IDEAmaven…

STM32中微秒延时的实现方式

STM32中微秒延时的实现方式 0.前言一、裸机实现方式二、FreeRTOS实现方式三、定时器实现&#xff08;通用&#xff09;4、总结 0.前言 最近在STM32驱动移植过程中需要用到微秒延时来实现一些外设的时序&#xff0c;由于网上找到的驱动方法良莠不齐&#xff0c;笔者在实现时序过…

论文阅读:One Embedder, Any Task: Instruction-Finetuned Text Embeddings

1. 优势 现存的emmbedding应用在新的task或者domain上时表现会有明显下降&#xff0c;甚至在相同task的不同domian上的效果也不行。这篇文章的重点就是提升embedding在不同任务和领域上的效果&#xff0c;特点是不需要用特定领域的数据进行finetune而是使用instuction finetun…

【数据结构】冒泡排序 (码源实现)

冒泡排序 前言一、冒泡排序运行图例二、算法实现基本思路三、算法实现步骤四、算法码源详解五、冒泡排序效率分析&#xff08;一&#xff09;时间复杂度——O&#xff08;N^2&#xff09;&#xff08;二&#xff09;空间复杂度——O&#xff08;1&#xff09;&#xff08;三&am…