vue3源码(七)渲染原理-h()

1.定义

h函数是创建节点, 可实现展示template如何渲染到html中的过程,因为vue渲染到页面上是通过loader打包成模板字符串拼接渲染的,所以 h 函数同样也是通过字符串渲染到html

h函数就是vue中的createElement方法,这个函数作用就是创建虚拟dom,追踪dom变化的

2.使用

/*** h()参数数量* 1个:类型* 2个:类型 和 属性、节点、儿子* 多个:第三个及其以后都是子节点* 不能出现三个参数,2不是属性 只要有三个参数就会认为第二个参数是属性*/const ele = h("h1");const ele1 = h("h1", "hello world");const ele2 = h("h1", { style: { color: "red" } });const ele3 = h("h1", ["hello world","goodbye"]);const ele4 = h("h1", {},"hello world","goodbye");

如果有三个及其以上的参数,第二个参数代表属性,如果没有属性,可以写成ele3或者ele4的形式

3.实现

2.1 创建虚拟节点

import { isString, ShapeFlags } from "@vue/shared";export function isVnode(value) {return value && value?.__v_isVnode;
}
export function createVnode(type, props, children) {const shapeFlag = isString(type) ? ShapeFlags.ELEMENT : 0;const vnode = {__v_isVnode: true,type,props,children,key: props?.key, // diff需要的keyel: null, // 虚拟节点对应的真实节点shapeFlag,};if(children){let type = 0;if(Array.isArray(children)){type = ShapeFlags.ARRAY_CHILDREN;}else{children = String(children);type = ShapeFlags.TEXT_CHILDREN}vnode.shapeFlag |= type
}
return vnode;
}

2.2 h实现

import { isObject } from "@vue/shared";
import { createVnode, isVnode } from "./createVnode";export function h(type, propsOrChildren?, children?) {let l = arguments.length;if (l === 2) {// 虚拟节点 | 属性if (isObject(propsOrChildren) && !Array.isArray(propsOrChildren)) {if (isVnode(propsOrChildren)) {return createVnode(type, null, [propsOrChildren]);} else {return createVnode(type, propsOrChildren, null);}}// 数组 | 文本return createVnode(type, null, propsOrChildren);} else {if (l > 3) {children = Array.from(arguments).slice(2);}if (l == 3 && isVnode(children)) {children = [children];}return createVnode(type, propsOrChildren, children);}
}

2.3 卸载DOM

const ele3 = h("h1", 'hello');render(ele3, app);setTimeout(()=>{render(null, app);},1000)

在挂载元素时纪录真实节点

const mountElement = (vnode, container) => {const { type, children, props, shapeFlag } = vnode;// 第一次渲染的时候我们让虚拟节点和真实的dom创建关联// 第二次渲染新的vnode,可以和上一次的vnode做比对,之后更新对应的el元素,可以复用这个dom元素let el = (vnode.el = hostCreateElement(type));...}

在渲染时判断

 const unmount = (vnode) => hostRemove(vnode.el)// core 中不关心如何渲染const render = (vnode, container) => {if (vnode == null) {// 移除dom元素if (container._vnode) {unmount(container._vnode)}}...}

2.4 对比节点

通过判断两个节点的类型和key值是否相同判定为是否为同一节点,如果不是,则删除n1,创建n2,如果是同一节点,则采用diff算法对比更新复用节点

export function isSameVnode(n1,n2){return n1.type === n2.type && n1.key === n2.key
}

更改patch逻辑

const patch = (n1, n2, container) => {if (n1 == n2) {return;}if (n1 && !isSameVnode(n1, n2)) {unmount(n1);n1 = null; //为了执行后续的n2的初始化}if (n1 == null) {mountElement(n2, container);}else{// diff 算法}};

diff算法见下篇啦~~~

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

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

相关文章

Python编程学习第一篇——Python零基础快速入门(六)(2)

上节讲了运算符,这节开始讲解Python的语法结构。前面一些章节我们对Python基础知识已经有了一些了解,包括Python数据类型、变量、语句、注释等等,也分享了一些可以运行小程序(小游戏),让大家在其中体会变量、语句、注释和数据类型等的运用。其中也涉及了一些语法结构,有…

PreparedStatement can have at most 65535 parameters

在 JDBC 中,由于内部实现的限制,PreparedStatement 能够接受的参数个数不能超过 65535 个 原因: PreparedStatement可以包含最多65,535个参数,‌这是因为PreparedStatement接口设计时,‌为了支持大量的参数化查询&am…

Windows 2012安装之实现远程连接

新建虚拟机 点击稍后安装操作系统 点击Microsoft Windows(W) 选择Windows Server 2012 设置虚拟机名称、安装位置 选择你的电脑核数 点击编辑虚拟机设置 点击CD/DVD(SATA) 使用ISO映像文件(M) 配置完之后点击确定 然后开启虚拟机 下一步: 点击现在安装&#xff1a…

【学习笔记】无人机(UAV)在3GPP系统中的增强支持(十二)-无人机群在物流中的应用

引言 本文是3GPP TR 22.829 V17.1.0技术报告,专注于无人机(UAV)在3GPP系统中的增强支持。文章提出了多个无人机应用场景,分析了相应的能力要求,并建议了新的服务级别要求和关键性能指标(KPIs)。…

常用的点云预处理算法

点云预处理是处理点云数据时的重要部分,其目的是提高点云数据的质量和处理效率。通过去除离群点、减少点云密度和增强特征,可以消除噪声、减少计算量、提高算法的准确性和鲁棒性,从而为后续的点云处理和分析步骤(如配准、分割和重…

【Git】执行git clone / checkout 命令出现 git Filename too long

执行 git clone / checkout 命令出现错误 git Filename too long 原因是因为目录中个别文件的文件名长度太长,超过了win文件名限制的260长度 解决方案 全局配置git git config --system core.longpaths true查看 git config --get core.longpaths设置完成后即可c…

Spring中的常用注解(一)

目录 RequestMapping PostMapping RequestBody Controller ResponseBody RestController Autowired Qualifier Primary Service Component Bean和Configuration ---------------- RequestMapping RequestMapping 是 Spring Framework 中用于配置 URL 映射的…

三大知名向量化模型比较分析——m3e,bge,bce

先聊聊出处。 M3E 是 Moka Massive Mixed Embedding 的缩写, Moka,此模型由 MokaAI 训练,开源和评测,训练脚本使用 uniem ,评测 BenchMark 使用 MTEB-zhMassive,此模型通过千万级 (2200w) 的中文句对数据…

常用图像分类、目标检测模型性能测试

说明 测试常用CV模型在单张图像上的识别速度,不包含图像读取时间,但包含图像预处理。可以在以后的应用中根据硬件配置选取合适的模型,达到最佳效果。其中推理速度为正常推理的速度,加速CPU使用openvino加速,GPU使用te…

智慧电子班牌系统,智慧班牌源码,为校园提供了便捷、高效、智能的信息管理和服务方式

智慧班牌在实现智慧校园的数字化建设中扮演着重要角色,它通过集成多种技术和功能,为校园提供了便捷、高效、智能的信息管理和服务方式。以下是智慧班牌如何实现智慧校园的数字化建设的具体方式: 一、信息集成与展示 基础信息展示&#xff1a…

海外媒体发稿:葡萄牙-实现高效媒体软文发稿计划-大舍传媒

一、葡萄牙媒体环境概述 葡萄牙,位于欧洲大陆西南端的国家,拥有丰富的文化和历史。在这个国家,媒体行业也有着相当大的影响力。葡萄牙的媒体环境多元化,包括电视、广播、报纸、杂志和互联网等各个领域。 二、葡萄牙媒体发稿的重…

ABC分析模型详解

ABC分析模型详解与Python代码示例 一、ABC分析模型概述 ABC分析模型,又称为ABC分类法、帕累托分析法或80/20规则,是一种广泛应用于库存管理、质量管理等领域的分析方法。该方法的核心思想是在众多因素中识别出少数起决定作用的关键因素和多数影响较小的…

如何恢复电脑上删除的文件?快速恢复被删除文件的技巧【5个实用方法】

如何恢复电脑上删除的文件?电脑误删文件的情况很经常发生,删除文件后第一时间可以按下组合键CtrlZ撤销,这样能挽回99%以上的文件。当然,如果已经彻底删除,那么可以了解下本文整理的方法找回。 (一&#xff…

【计算机网络】学习指南及导论

个人主页:【😊个人主页】 系列专栏:【❤️计算机网络】 文章目录 前言我们为什么要学计算机网络?计算机网络概述计算机网络的分类按交换技术分类按使用者分类按传输介质分类按覆盖网络分类按覆盖网络分类 局域网的连接方式有线连接…

【HarmonyOS学习】动画

页面分类动画 显示动画 function animateTo(value: AnimateParam, event: () > void): void;代码如下:(实现属性变化引发的动画) Entry Component struct Animate_Page1 {State boxWidth: number 100;State boxHeight: number 100;Sta…

第一节Linux常见指令

目录 1.Linux下基本指令 ls指令 pwd 命令 cd 指令 知识点:理解树形结构 touch 指令 mkdir指令(重要) rmdir指令 && rm指令(重要) 知识点:ls file* 可以找到当前目录下任何以file开头的文件​编辑 知识点:热键 man指令()重要 补充知识点:nano cp…

前端程序员应该往全栈方向发展吗?还是坚守前端?

作者:寒蝉(知乎) 顺便吆喝一声,技术大厂,内推捞人,前/后端or测试←感兴趣 要求学历:全日制统招本科(非学院派即可): --加班偶尔较多,但周末加班两…

深入理解 Java 中 forEachOrdered 和 forEach 方法的区别

在 Java 8 中引入的 Stream API 提供了丰富的操作方法来处理集合数据。其中,forEachOrdered 和 forEach 是两个常用的方法,用于对集合中的元素进行操作。虽然它们看起来很相似,但它们在处理元素顺序上有着重要的区别。本文将深入探讨它们的不…

Android NDK开发之震动服务客户端编写程序(C++)

一、背景 最近有个小伙伴问我可不可以写一个可执行程序(C/C) 来实现Android设备的震动的功能。 作为一个多年的Android开发者,我觉得这是可以实现的。 但是由于过去我一直做App开发,也就把这个实现过程想简单了。 经过了几天的折腾,终于算是…

港股指数实时行情API接口

港股 指数 实时 行情 API接口 # Restful API https://tsanghi.com/api/fin/index/HKG/realtime?token{token}&ticker{ticker}指定指数代码,获取该指数的实时行情(开、高、低、收、量)。 更新周期:实时。 请求方式&#xff1a…