目录 h()函数和createVNode()函数的使用 使用方法 VUE3中h方法和createVnode的实现 在公共包shared里写上ShapeFlags 在runtime-core模块里创建vnode.ts文件专门处理虚拟节点 为了后续的diff算法,我们要
目录
- h()函数和createVNode()函数的使用
- 使用方法
- VUE3中h方法和createVnode的实现
- 在公共包shared里写上ShapeFlags
- 在runtime-core模块里创建vnode.ts文件专门处理虚拟节点
- 为了后续的diff算法,我们要给这个虚拟节点上加一些属性和标识
- h的用法
- 创建h.ts文件来写h方法
h()函数和createVNode()函数的使用
使用方法
- h(标签, {属性},内容)
- h(标签, {属性},[可以继续嵌套h()])
- createVNode(标签, {属性},内容)
- createVNode(标签, {属性},[可以继续嵌套createVNode()])
其实h()函数和createVNode()函数都是创建dom节点,他们的作用是一样的,但是在VUE3中createVNode()函数的功能比h()函数要多且做了性能优化,渲染节点的速度也更快。
import { createApp } from "vue"; //import App from "./App.vue"; import { defineComponent, h, createVNode } from "vue"; import HelloWorld from "./components/HelloWorld.vue"; const img = require('./assets/logo.png'); // eslint-disable-line const App = defineComponent({ render() { return h("div", { id: "app" }, [ h("img", { src: img }), h(HelloWorld, { msg: "HelloWorld" }), createVNode("h1", { class: "hello" }, "HelloWorld") ] ); }, }); createApp(App).mount("#app");
渲染出来的结果为:
VUE3中h方法和createVnode的实现
h方法是给用户来用的,它具备着多样性。我们先来写createVnode
在公共包shared里写上ShapeFlags
采用二进制来标识某些东西
在runtime-core模块里创建vnode.ts文件专门处理虚拟节点
虚拟节点有很多,组件的、元素的和文本的
用ShapeFlags来判断是否是字符串,判断儿子children是否是个数组
children不是数组类型,则标识为text_children
将不同情况打上ShapeFlag标识
最后把来共同标识这个vode节点的类型
为了后续的diff算法,我们要给这个虚拟节点上加一些属性和标识
h的用法
h(‘div') h(‘div',{style:{‘color':‘red'}},‘hello') h(‘div',‘hello') h(‘div',h(‘span')) h(‘div',[h(‘span'),h(‘span')]) h(‘div',null,‘hello',‘world') h(‘div',null,h(‘span')) h(‘div',null,[h(‘span')])
创建h.ts文件来写h方法
先判断参数长度
如果参数长度等于2,那么我们要区分一下第二个参数是个h方法处理过的虚拟节点,还是一个普通的属性对象,或者是一个数组
如果第二个参数是不是一个数组并且也不是一个对象,那么判断第二个参数是否是h方法处理过的虚拟节点,如果是虚拟节点,那么调用createVnode,第二个参数传null,第三个参数包装成数组。如果不是虚拟节点,那肯定就是普通属性
如果第二个参数是数组或者不是对象,第二个参数传null,直接把propsChildren传入第三个参数,传第三个参数后,都可以处理到,包括文本元素
如果参数长度大于3,后续的参数包装成一个数组
如果参数长度等于3,并且children是一个虚拟节点,children包装成一个数组
最后统一调createVnode
总结,其实我们上述的一系列判断的核心是处理传入createVnode的第三个参数,这个参数只可能是文本或者数组
以上为个人经验,希望能给大家一个参考,也希望大家多多支持易盾网络。