「这是我参与2022首次更文挑战的第6天,活动详情查看:2022首次更文挑战」。
虚拟DOM
虚拟DOM指:用JavaScript描述DOM的层次结构。DOM中的一切属性都在虚拟DOM中有对应的属性。
真实DOM:
虚拟DOM:
diff是发生在虚拟DOM上的: 新虚拟DOM和老虚拟DOM进行diff(精细化比较),算发出应该如何最小量更新,最后反映到真正的DOM上。
h函数
作用:用来产生虚拟节点(vnode)
举例:
这样调用h函数:
h('a',{props:{href:"https://juejin.cn/"}},"掘金"};
将得到这样的虚拟节点:
{sel:"a",data:{props:{href:"https://juejin.cn/"}},text:"掘金"};
他表示的真正的DOM节点:
<a href="https://juejin.cn/">掘金</a>
虚拟节点的属性
属性分别为:children、data、elm、key、sel、text
var vnode = h(
'a', {
props: {
href: 'https://juejin.cn/',
target: "_blank",
},
},
'掘金',
)
h函数可以嵌套使用,从而得到虚拟DOM树: h函数的用法很活,不一定要按着模板书写。
h("li", "倒霉死勒"),
h("li", "林予曦"),
h("li", [
h("p", "苏尚卿"),
h("p", "谷江山"),
]),
h("li", h("p", "锦鲤")),
])
手写h函数
h函数的形式有很多,比如:
h("div"), h("div",{},),h("div",{},"text"),这里指讨论h函数必须传入三个参数的情况,即必须传入sel、data和第三个参数(可以是text、array、object)
vnode函数:功能很简单,只是将传入的参数转换成一个对象返回。
export default function (sel, data, children, text, elm) {
return {
sel,
data,
children,
text,
elm
}
}
h函数:主要函数,将传入的参数转换成对象。
export default function (sel, data, c) {
if (arguments.length != 3) {
throw new Error("must three elements");
}
if (typeof c == "string" || typeof c == "number") {
return vnode(sel, data, undefined, c, undefined);
} else if (Array.isArray(c)) {
let children = [];
for (let i = 0; i < c.length; i++) {
if (!(typeof c[i] == "object" && c[i].hasOwnProperty("sel"))) {
throw new Error("数组中有项类型不对");
}
children.push(c[i]);
}
return vnode(sel, data, children, undefined, undefined)
} else if (typeof c == "object" && c.hasOwnProperty("sel")) {
let children = [c];
return vnode(sel, data, children, undefined, undefined)
} else {
throw new Error("传入类型不正确");
}
}
步骤:
- 第一步:检查参数的个数;
- 第二步:因为第一个参数必须是sel,第二个参数必须是data,所以检查第三个参数的类型;
判断第三个参数:
1、如果第三个参数是简单数据类型,如字符串或数字类型,可以直接作为text属性的属性值返回;
2、如果第三个参数是数组类型,则将数组子项作为children返回;
3、如果第三个参数是对象类型,则就可视为唯一的children子项。