vue diff算法与虚拟dom知识整理(5) 手写一个自己的h函数

news/2024/11/7 19:28:17/

本文的意义在于教会大家如何手写一个h函数

上文中 我们简单理解了一下h函数 他的作用是构建一个虚拟的dom节点
掌握这个函数还是很有必要的 首先 你想要写出来 还是得去看原版的ts代码

这边 我们没必要把太多注意力放在TS上 所以 我们这边是看ts代码 然后 仿写js代码

我们在 案例的 node_modules 下找到 snabbdom/src/h.ts 打开这个文件
在这里插入图片描述
读h函数 你会发现 他最后 是返回的用了一个 vnode函数
在这里插入图片描述
好家伙 在这套娃呢
我们打开同目录下的vnode.ts

这个 vnode函数 看着就相对简单一些了
在这里插入图片描述
简单说 就是接了一些列参数 并给这些参数限制了类型
在ts中 sel: string | undefined 的意思就是
接受一个 参数 代理名定位以为 sel :后的内容代表 可以是string字符串类型 或者 也可以是 undefined 未定义

处理外这些参数之后 就把他们转成一个json并返回
所以 h函数最后返回vnode 就是返回一个vnode函数处理好的虚拟节点对象

对象中比较麻烦的 是这个 children 因为他存在嵌套的可能 就是 一个虚拟节点里面可能又套了一个虚拟节点 被套的虚拟节点 下面 可能还有n层这样嵌套的虚拟节点

所以 我们看h函数上面这个位置
会循环处理children 一层一层 都创建出 vonde节点
在这里插入图片描述
这里 h函数是不涉及递归的 就是用循环 一层一层往下调

这里 我们看到上面有很多的if h函数这个位置 就是涉及到 h函数重载
在这里插入图片描述
重载的概念很多后端语言都有 ts也将这种概念带入了前端开发中
就是定义很多一样名字的函数 接收的参数 类型 数量 不同 调用不同的逻辑函数
如果您不了解 可以读一下我的文章
TypeScript方法重载
上文我们演示过
知道了 h函数 有非常多的调法
在这里插入图片描述

好 那么 我们就来试着写一个自己的h函数

我们看到我们一直在写的这个按理 在根目录下的src下创建一个文件夹 叫 snabbdom

然后在我们刚创建的 snabbdom 下创建一个 h.js
然后 我们刚才也看了 h函数返回 需要一个vnode函数来处理一下格式
所以 在snabbdom下再创建一个 vnode.js
参考代码如下

export default function(sel,data,children,text,elm) {let key = data.key?data.key:undefined;return {sel,data,key,children,text,elm}
}

逻辑非常简单
就是 导出了一个函数 这个函数接收五个参数
然后 先定义一个局部变量 叫 key 他的赋值 用了一个三元运算符
判断 如果 data中有一个key字段 那么 就用 data里的key给key赋值
如果没有 则 key等于key:undefined
然后返回一个对象 就是 字段名 等于字段对应的值 学过ES6的朋友会理解

{key
}

{key: key
}

是一个意思

然后 我们来写刚刚创建的 h.js 内的代码

然后 首先要说明 我们这边h函数 不处理方法的重载 因为 重载这个 理解了概念 谁都可以写出来 很麻烦 而且他我觉得并不算h函数中很美观的东西
所以 我们这样写的函数 就必须要传三个参数

然后 我们 h.js编写代码如下

//引入我们刚刚写的vnode
import vnode from "./vnode";
//默认导出一个函数
export default function(a,b,c) {//确认调用时是否传了三个参数if(arguments.length != 3)//如果参数不是三个  抛出异常警告throw new Errow("对不起,本h函数必须传三个参数 我们是低配版");//  判断 如果传入的第三个参数 是  string或者number  表示 形态为 第一种  h(标签。属性,文本)if(typeof c == "string"||typeof c == 'number') {return vnode(a,b,undefined,c,undefined);//如果传的是一个数组  那么 是调的第二种形式  h(标签。属性,数组)}else if(Array.isArray(c)) {//定义一个children数组  来存一下当前这个节点的子集let children = [];//循环c这个数组for(let i = 0;i < c.length;i++) {//判断当前下标是不是一个对象  因为h函数一定会返回一个对象if(c[i] instanceof Object) {children.push(c[i]);}else{//如果不是 抛出异常提示throw new Errow(`第三个参数的第${(i+1)}项不是一个h函数`);}}//循环结束  表示children收集子集也结束了return vnode(a,b,children,undefined,undefined);//判断c是否是一个对象  如果是  表示调用了第三种  h(标签。属性,h对象)}else if(c instanceof Object) {//第三种 说明  他是唯一的子集  我们直接将他的子集放入children就好了return vnode(a,b,[c],undefined,undefined);//如果以上格式 全部都不符合  排除错误}else{throw new Errow("对不起,传入的第三个参数格式错误 请认真加粗");}
}

因为这个东西比较不太好去叙述 所以 我就比较努力的写注释 希望大家能通过注释来理解了
这个不叫递归 是相互嵌套 h函数的思维真的很巧妙 没有很复杂的代码 但设计思维 却人感觉很有趣 也很巧妙

然后 我们来测试三种情况
我们将 src下的 index.js 代码改写如下

import h from "./snabbdom/h";const dom1 = h("div",{props: {class: "dom"}
},"文本测试");const dom2 = h("div",{props: {class: "dom"}
},[h("div",{},"java"),h("div",{},"html"),h("div",{},[h("div",{},"react"),h("div",{},"css")])
]);const dom3 = h("div",{props: {class: "dom"}
},h("div",{},"java"));console.log(dom1);
console.log(dom2);
console.log(dom3);

这里 我们传了 第三个的各种情况 文本 数组 直接一个h函数
然后 我们运行项目
在这里插入图片描述
这三种 我们都打开看一下

第一种
在这里插入图片描述
第二种
在这里插入图片描述
第三种
在这里插入图片描述


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

相关文章

DDR基础

欢迎关注我的博客网站nr-linux.com&#xff0c;图片清晰度和&#xff0c;排版会更好些&#xff0c;文章优先更新至博客站。 DDR全称Double Data Rate Synchronous Dynamic Random Access Memory&#xff0c;是当代处理器必不可少的存储器件之一。本文关于DDR介绍的核心点如下&…

frp将配置写在代码中重新打包

frp 是一个专注于内网穿透的高性能的反向代理应用&#xff0c;支持 TCP、UDP、HTTP、HTTPS 等多种协议。可以将内网服务以安全、便捷的方式通过具有公网 IP 节点的中转暴露到公网。在有些情况下我们需要隐藏配置信息&#xff0c;尤其是客户端&#xff08;比如我们要在第三方电脑…

《物联网安全关键技术白皮书》解读

物联网技术作为物理世界与信息世界融合的具象体现&#xff0c;有效地连接分离的物理世界和信息空间&#xff0c;囊括了传感器网络、通信网络以及互联网&#xff0c;构建物与物互联、人与物互联、人与人互联的协同共生关系&#xff0c;推进了信息产业的新变革&#xff0c;同时也…

《精英的傲慢:好的社会该如何定义成功》笔记与摘录

目录 作者简介 书内容简介 经典摘录 1、现状与现象 2、什么是优绩至上原则 3、对优绩至上原则赞同与否的讨论 4、 优绩至上原则存在的争议点 5、 作为哲学家&#xff0c;桑德尔从道德哲学角度的思考 6、作者对优绩制的批判 7、流动性与平等的关系 8、我们该如何摆脱优…

基于单片机的数字频率计设计

数字频率计概述 数字频率计是计算机、通讯设备、音频视频等科研生产领域不可缺少的测量仪器。它是一种用十进制数字显示被测信号频率的数字测量仪器。它的基本功能是测量正弦信号&#xff0c;方波信号及其他各种单位时间内变化的物理量。在进行模拟、数字电路的设计、安装、调试…

176_工具_Power BI 实用工具 pbi-utils 更新至 v1.0.3.1

176_工具_Power BI 实用工具 pbi-utils 更新至 v1.0.3.1 pbi-utils 更新至&#xff1a;v1.0.3.1, 从 v1.0.0.0 到 v1.0.3.1 更新了 8 次。 文档地址&#xff1a;https://jiaopengzi.com/2880.html 主要功能&#xff1a; 快速设置 Power BI 模板&#xff0c;实现高复用。设计…

定时清理文件脚本

一、定时清理文件 编写一个bat脚本。新建一个文本文档&#xff08;txt文件&#xff09;&#xff0c;在里面输入echo offdel /f /s /q E:\temp\*.*&#xff0c;E代表E盘&#xff0c;temp是E盘下的需要清理的文件夹&#xff0c;运行脚本后&#xff0c;就是清理E:\temp文件夹下的…

【地铁上的设计模式】--行为型模式:解释器模式

什么是解释器 解释器&#xff08;Interpreter&#xff09;是一种行为型设计模式&#xff0c;它用于解释一种特定的编程语言或表达式。它提供了一种解释一组语言语法的方法&#xff0c;使得用户可以按照特定的规则定义自己的语言&#xff0c;并通过解释器将其转化成可执行代码。…