VUE源码解析:4、手写一个低配版的h函数

创建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);

在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值