Snabbdom(虚拟dom-6-createElm函数)

37 篇文章 3 订阅
16 篇文章 1 订阅

createElm

  function createElm(vnode: VNode, insertedVnodeQueue: VNodeQueue): Node {
    let i: any;
    let data = vnode.data;
    if (data !== undefined) {
      // 执行用户设置的init钩子函数
      const init = data.hook?.init; // 用户传递的init函数
      if (isDef(init)) {
        init(vnode); // 调用init后,可能改变vnode的内容
        data = vnode.data; // 所以再次进行赋值;
      }
    }
    // 把vnode转换成真实DOM对象(没有渲染到页面)
    const children = vnode.children;
    const sel = vnode.sel;
    if (sel === "!") {
      //  注释节点
      if (isUndef(vnode.text)) {
        vnode.text = "";
      }
      vnode.elm = api.createComment(vnode.text!);
    } else if (sel !== undefined) {
      // 如果选择器不为空
      // 解析选择器
      // Parse selector
      const hashIdx = sel.indexOf("#"); // #位置
      const dotIdx = sel.indexOf(".", hashIdx); // .的位置
      const hash = hashIdx > 0 ? hashIdx : sel.length;
      const dot = dotIdx > 0 ? dotIdx : sel.length;
      const tag =
        hashIdx !== -1 || dotIdx !== -1
          ? sel.slice(0, Math.min(hash, dot))
          : sel; // 标签名
      const elm = (vnode.elm =
        isDef(data) && isDef((i = data.ns))
          ? api.createElementNS(i, tag, data)
          : api.createElement(tag, data));
      if (hash < dot) elm.setAttribute("id", sel.slice(hash + 1, dot));
      if (dotIdx > 0)
        elm.setAttribute("class", sel.slice(dot + 1).replace(/\./g, " "));
      // 执行模块的create钩子函数
      for (i = 0; i < cbs.create.length; ++i) cbs.create[i](emptyNode, vnode);
      // 如果vnode中有子节点,创建子vnode对应的DOM元素并追加到DOM树上;
      if (is.array(children)) {
        for (i = 0; i < children.length; ++i) {
          const ch = children[i];
          if (ch != null) {
            // 如果子节点不为空,递归调用子节点,追加在对应父节点上
            api.appendChild(elm, createElm(ch as VNode, insertedVnodeQueue));
          }
        }
      } else if (is.primitive(vnode.text)) {
        // 如果vnode的text值是 string/number,创建文本节点并追加到 DOM树上
        api.appendChild(elm, api.createTextNode(vnode.text));
      }
      const hook = vnode.data!.hook;
      if (isDef(hook)) {
        // 执行用户传入的钩子 create
        hook.create?.(emptyNode, vnode);
        if (hook.insert) {
          // 把vnode 添加到队列中,为后续执行insert钩子做准备
          insertedVnodeQueue.push(vnode);
        }
      }
    } else {
      // 选择器为空,创建文本节点
      vnode.elm = api.createTextNode(vnode.text!);
    }
    // 返回新创建的DOM
    return vnode.elm;
  }

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值