这是一个系列文章,请关注snabbdom@3.5.1 源码分析专栏、vue@2.6.11 源码分析 专栏
h函数(创建虚拟DOM)
h
可以理解为createVirtualDom即创建虚拟节点。
export function h(sel, b, c) {
//... 由于h函数有多重重载形式,这部分是处理参数
if (children !== undefined) {
for (i = 0; i < children.length; ++i) {
// 如果孩子是原始类型,直接创建vnode
if (is.primitive(children[i]))
children[i] = vnode(undefined, undefined, undefined, children[i], undefined);
}
}
//... svg情况 添加namespace
return vnode(sel, data, children, text, undefined);
}
- 传递的children正常应该是一个vnode,不过如果是原始类型,框架会帮你处理。
new vnode(...)
并返回- 注意:
children
和text
只会有一个生效传递给vnode
构造函数,见源码:h.ts-因为else-if
vnode
export function vnode(sel, data, children, text, elm) {
const key = data === undefined ? undefined : data.key;
return { sel, data, children, text, elm, key };
}
就是这么简单,一个js对象,别无其他。 重点看看每个属性的类型,参考
- sel:如
div#container.classA.classB
- data
- 存储一些信息以提供给模块访问,模块会在某些
钩子
(可以理解为真实DOM在创建和更新过程的生命周期)中根据这些信息来设置真实DOM信息,比如设置class、样式、事件、属性等等。 - snabbdom本身并没有限制data中的内容,如果开发者提供了自己的module希望在创建真实DOM时用到某些信息,就可以放到dat中,当调用该module钩子时,可以拿到这些信息。
- 存储一些信息以提供给模块访问,模块会在某些
- children:孩子虚拟节点
- text:创建一个文本类型虚拟节点,作为
sel
的孩子(注意:会假设sel
只有这一个孩子) - elm:该虚拟节点关联的真实DOM
- key:标识虚拟节点,通常在列表处用到,以达到复用真实DOM效果从而提供性能(创建真实DOM耗费性能)
总结
没什么好说的,下节说下init
函数及其返回的patch
函数