创建mysnabbdom文件夹,实现h.js和vnode.js
1、实现vnode.js,(vnode的本质是,把传入的参数,组合成对象返回,得到的也就是前文所说的虚拟dom)
// 函数的功能,就是把传入的5个参数组合成对象返回
export default function(sel, data, children, text, elm) {
return {
sel: sel,
data: data,
children: children,
text: text,
elm: elm,
}
}
2、h.js引入vnode
import vnode from './vnode.js'
console.log(vnode('div',2,3,4,5))
// 实现一个低配版本的h函数,查下第四项。
3、index.js引入h函数
import h from "./mysnabbdom/h.js"
vnode.js就是把h.js中传入的5个参数组合成了对象返回
4、实现一个低配版本的h函数
import vnode from './vnode.js'
// 实现一个低配版的h函数,这个函数必须接受3个参数,缺一不可
// 相当于它的重载功能较弱
// sel:标签
// data:函数
// c:不确定具体是什么类型
// 形态1、h('div', {}, '文字')
// 形态2、h('div', {}, [])
// 形态3、h('div', {}, h())
// 也就是说调用的时候必须是上面的三种之一
export default function(sel, data, c) {
// 本次函数调用时传入函数的实参数量 != 3
if(arguments.length != 3){
throw new Error('对不起,h函数必须接受3个参数')
}
//检查参数c的类型
if(typeof c == 'string' || typeof c == 'number'){
// 1、说明现在调用h函数的是:形态1
return vnode(sel, data, undefined, c, undefined)
}else if(Array.isArray(c)){
// 2、说明现在调用h函数的是:形态2
// 遍历c,检查c[i]的每一项必须是一个对象,并且要有'sel'属性,如果不满足就报错
let children = [];
for(let i = 0; i<c.length; i++){
// h函数的运行结果一定是一个对象
if(!(typeof c[i] == 'object' && c[i].hasOwnProperty('sel'))){
throw new Error('传入的数组函数中,有一项不是h函数')
// 这里不需要执行c[i],因为你的测试语句已经有了执行
}else{
// 此时只需要收集c[i]的每一项
children.push(c[i])
}
}
// 循环结束,说明children收集完毕,可以返回虚拟节点了,
return vnode(sel, data, children, undefined, undefined)
}else if(typeof c == 'object' && c.hasOwnProperty('sel')){
// hasOwnProperty() 方法会返回一个布尔值,指示对象自身属性中是否具有指定的属性(也就是,是否有指定的键)。
// 3、说明现在调用h函数的是:形态3
// 即,传入的c是唯一的children,不用执行c,因为测试语句中已经执行了c。
let children = [c];
return vnode(sel, data, children, undefined, undefined)
}else{
throw new Error('对不起,传入的第三个参数类型错误')
}
}
index.js测试刚才实现的低配版h函数
import h from "./mysnabbdom/h.js"
// 形态1,直接返回虚拟节点。
var vnode1 = h('div', {}, '文字')
console.log('形态1');
console.log(vnode1);
// 形态2,需要遍历数组中的h函数。
var vnode2 = h('div', {}, [
h('p', {}, '哈哈'),
h('p', {}, '嘻嘻'),
h('p', {}, [
h('span', {}, 'A'), // 这里直接执行了形态1,返回虚拟节点。
h('span', {}, 'B'),
]),
])
console.log('形态2');
console.log(vnode2);
// 形态3:只有一个h函数
var vnode3 = h('div', {}, h('span', {}, 'C'))
console.log('形态3');
console.log(vnode3);