Vue源码学习(二): 手写简单版 h 函数

相信使用过vue的朋友都对这个h函数不陌生了,在vue中是通过调用 h 函数来生成虚拟DOM,今天就来简单实现一下这个 h 函数的功能。

目录结构
在这里插入图片描述
安装的依赖。这里的snabbdom依赖很重要,它是实现Virtual DOM的一种。
在这里插入图片描述
然后就是webpack的配置了
在这里插入图片描述

在vnode.js文件中把传入的5个参数组合成对象再返回。

在这里插入图片描述

在这里调用h函数时会有三种形态,前两个参数都是一样的,第一个就是结点的便签名了,第二个参数就是一个对象,用来保存ID名、类名的,第三个参数是用来保存数据的,比如文字、数组或者在这个标签是否有子元素,有的话也会在调用一次h函数进行递归并且保存在这里面。

接下来看代码

import vnode from './vnode.js'

// 调用时的形态:
// 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个参数')
  }
  // 检查参数 c 的类型
  if (typeof c == 'string' || typeof c == 'number') {
    // 调用形态 1
    return vnode(sel, data, undefined, c, undefined)
  } else if (Array.isArray(c)) {
    // 调用形态 2
    let children = [];
    // 遍历 c 收集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]
      children.push(c[i])
    }
    // 循环结束 说明children收集结束
    return vnode(sel, data, children, undefined, undefined)
  } else if (typeof c == 'object' && c.hasOwnProperty('sel')) {
    // 调用形态3
    let children = [c]
    return vnode(sel, data, children, undefined, undefined)
  } else {
    throw new Error('传入的第三个参数类型错误')
  }
}

,首先是暴露一个方法出去,并且这个方法需要传入三个参数,就是上面说的三个。进到这个函数中来,一开始就是需要判断参数是否符合三个,不符合则抛出异常

在这里插入图片描述

然后就是判断第三个参数c的类型了,当传入的是string、number类型的数据时,则调用第一种形态,h(‘div’, {}, ‘文字’)。

将children、elm参数设置为undefined并返回
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述


然后就是调用形态二了,首先要判断是否为一个数组,然后呢因为传入的是数组,这个时候就需要用到遍历了
这里需要声明一个children变量,然后遍历传入的 c 参数,还需要判断里面的每个元素是否为对象,并且还要求它拥有 “sel” 属性,也就是标签名,不符合则抛出错误,符合则将其收集到children变量中,当循环结束时说明children收集结束,然后将其返回出去。

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述


形态三跟形态二实际上是差不多的,只不过形态二是调用多个 h 函数,也就是里面有多个子元素,而形态三只调用一次 h 函数即一个元素。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值