微型Vue框架构建Part3——$Mount方法实现

  • 如何给Vue对象的原型链添加$Mount方法initMout
  • 为真实节点生成虚拟DOM,具体实现方法contrucVNode
  • 定义虚拟Node节点类, VNode
  • $Mount方法实现概览

image.png

相关链接

如何给Vue对象的原型链添加$Mount方法

  • initMout方法导出,传入Vue对象
    /**
     * 在原型链上添加#mount方法
     * @param {*} Vue
     */
    export function initMout(Vue) {
      Vue.prototype.$mount = function (el) {
        const vm = this;
        this._el = el;
        mount(vm, el);
      };
    }

复制代码

将真实节点生成虚拟DOM

  • 每个真实DOM节点都会继承Node类,所以通过nodeName能知道是HTML标签类型还是文本类型。(PS:node类的属性和方法
  • nodeType的值代表不同的含义,典型有1表示HTML标签,3表示文本标签(PS:nodeType的值有哪些,代表什么意思
  • nodeName是怎么定义文本类型的:两个节点间的空白部分和实际的文字都是文本类型
    1. <div id="app">标签后开始到 “文本内容”这个文字前是一个文本类型#text

    2. “文本类容”文字到 <span>标签前 是一个文本类型#text

    3. <span class="a">{{content}}</span>是个SPAN类型

         <div id="app"> 
           文本内容:<span class="a">{{content}}</span> 
        </div>
    复制代码
  • children属性就是上面代码块生成的虚拟DOM

image.png

  • 代码实现

    /**
     *  构建虚拟DOM
     * @param {*} vm
     * @param {*} el 真实的DOM节点
     * @param {*} parent 父级节点
     */
    function contrucVNode(vm, el, parent) {
      const tag = el.nodeName;
      const children = []; // 虚拟DOM下的虚拟子节点
      const text = getTextContent(el);
      const data = "";
      const nodeType = el.nodeType;

      const vnode = new VNode(tag, el, children, text, data, parent, nodeType);

      // 真实DOM节点下是否还有子节点
      const childrenList = el.childNodes;

      for (let i = 0; i < childrenList.length; i++) {
        const childrenNode = contrucVNode(vm, childrenList[i], parent);
        if (childrenNode instanceof VNode) {
          vnode.children.push(childrenNode);
        }
      }

      return vnode;
    }

复制代码

定义虚拟Node节点类

    export default class Vnode {
      // node节点的内置属性和方法:https://developer.mozilla.org/en-US/docs/Web/API/Node
      // nodeType的值: https://developer.mozilla.org/zh-CN/docs/Web/API/Node/nodeType
      constructor(
        tag, // 标签类型, DIV、SPAN... #TEXT
        elm, // 对应真实节点,后期会根据这个属性操作真实DOM,如数据渲染
        children, // 当前节点下的虚拟子节点(虚拟DOM)
        text, // 当前节点中文本内容
        data, // VNodeData, 暂时保留,暂无意义
        parent, // 父级节点
        nodeType // 节点类型
      ) {
        this.tag = tag;
        this.elm = elm;
        this.children = children;
        this.text = text;
        this.data = data;
        this.parent = parent;
        this.nodeType = nodeType;

        this.env = {}; // 当前节点的环境变量
        this.instructions = null; // 存放Due指令,如v-for
        this.template = []; // 当前节点涉及到的模板语法——形如{{ text }}
      }
    }
复制代码
© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享