h 函数支持以下写法,此次手写 h 函数,只支持后面 3 种写法(低配版)
文件结构:
vnode.js
// 函数的功能非常简单,就是透传参数 export default function (sel, data, children, text, elm) { return { sel, data, children, text, elm } }
h.js
import vnode from './vnode.js' // 编写一个低配版本的h函数,这个函数必须接收3个参数,缺一不可 // 相当于重载功能较弱 // 调用的时候。形态必须是下面的三种之一: // 1. h('div', {}, '文字') // 2. h('div', {}, []) // 3. h('div', {}, h()) export default function(sel, data, c) { // 检查参数个数 if (arguments.length !== 3) { throw new Error('对不起,h函数必须传入3个参数,我们是低配版') } if (typeof c === 'string' || typeof c === 'number') { // 说明现在调用的是形态1 return vnode(sel, data, undefined, c, undefined); } else if (Array.isArray(c)) { // 形态2 // 遍历c,收集 let children = []; for (let i = 0; i < c.length; i++) { // 检查c[i]必须是一个对象,如果不满足 if (!(typeof c[i] === 'object' && c[i].hasOwnProperty('sel'))) { throw new Error('传入的数组参数中有一项不是h函数') } // 这里不用执行c[i],测试语句中以及执行了c[i],只需要收集到children就行了 children.push(c[i]) } return vnode(sel, data, children, undefined, undefined) } else if (typeof c === 'object' && c.hasOwnProperty('sel')) { // 形态3 return vnode(sel, data, [c], undefined, undefined) } else { throw new Error('传入参数有误') } }
index.js
import h from './mySnabbdom/h' // var myVnode1 = h('div', {}, 'test') // var myVnode1 = h('div', {}, []) // var myVnode1 = h('div', {}, h()) // var myVnode1 = h('div', {}, [ // h('div', {}, '菠萝'), // h('div', {}, '香蕉'), // h('div', {}, [ // h('div', {}, '火龙果'), // h('div', {}, '牛油果'), // ]), // ]) var myVnode1 = h('div', {}, h('p', {}, '香蕉')); console.log(myVnode1)