文章主要是帮助大家理解虚拟DOM的产生,不是如何从真实DOM转换成虚拟DOM,而是如何通过h函数产生虚拟DOM
-
真实DOM和虚拟DOM:如下图,真实DOM结构对应的虚拟DOM结构
-
h函数的作用:
手动往h函数中传入参数,h函数根据传入的参数,返回与之对应的虚拟DOM(也就是返回一个形如上图右边的对象) -
h函数的正确用法:sel:选择器,data:配置对象(标签中的属性class,href…),text:标签文本
- h(sel)
- h(sel,data)
- h(sel,data,text)
- h(sel,data,h(…))
- h(sel,data,[h(…),h(…))
-
为了让理解变得更简洁,我们只考虑h函数中传递三个参数的情况
/*
只考虑以下几种h函数
1.h(sel,data,text)
2.h(sel,data,[])
3.h(sel,data,h())
*/
export default function h(sel,data,c){
// 只考虑参数个数为3时的情况,其余情况抛异常
console.log(arguments.length);
if(arguments.length != 3){
throw new Error('输入的参数个数不正确')
}
// 将返回对象中的属性进行统一整理
let children = undefined
let elm = undefined
let text = undefined
if(typeof c === 'number' || typeof c === 'string'){ // c为文本
text = c
}else if(typeof c === 'object' && c.hasOwnProperty('sel')){ //c为h函数
children = [c]
}else if(Array.isArray(c)){ //c为数组,数组里面是多个h函数
children = []
for(let i=0;i<c.length;i++){
if(!(typeof c[i] === 'object' && c[i].hasOwnProperty('sel'))){
children = undefined
throw new Error('数组中可能存在不是h函数的参数')
}
children.push(c[i])
}
}
return vnode(sel,data,children,elm,text)
}
function vnode(sel,data,children,elm,text){
const key = data === undefined ? undefined : data.key
return {sel,data,children,text,elm,key}
}
- 测试
//测试代码
import h from "xxxx";
// 递归的形成关键在于h函数的调用
const vnode = h('ul',{},[
h('li',{},'Tom'),
h('li',{},'Jerry'),
h('li',{},h('a',{props:{href:'www.baidu.com'}},'欢迎来到百度'))
])
console.log(vnode);
结果: