vue2 模版编译start,end 和chars的方法介绍

77 阅读1分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第24天,点击查看活动详情

vue2模版编译-对剩余html字符串处理 和start函数的写法的start方法我们已经生成初步的AST树了,全部代码我就不贴了,这里主要是start,end 和chars这几个方法,

// 全局声明的变量
   let text = '';
   let root, currentParent,stack=[];
  function start(tagName, attrs) { // 这是对处理开始标签的数据数据函数
    // 开始创建AST树了
    const element = createASTElement(tagName,attrs)
    // 我们拿到我们使用开始标签创建的AST树
    // 后面我们要判断是不是头标签 就是用我们上的root
    if (!root) { // 如果没有root我们需要赋值
      root =  element 
    }
    currentParent = element // 这两个操作主要是我们在使用end的方法会用到
    stack.push(element) // 
  }

示例html模版

<div>
   <span>
      <a>
      
      </a>
   </span
</div
  

end的方法

// stack里面数组的 如 [div,span,a]
function end(tagName) { // 调用了end方法说明我们匹配的</ 闭合标签
  // 我们需要把之前在start函数里压入stack里的拿出来
   const element = stack.pop(); // 拿出来就是a 说明a标签全部遍历完了
   // 然后在数组里拿到a标签的父级
   currentParent = stack[stack.length-1] 
   // 判断 currentParent存在就说明有父级 需要给AST树赋值了
   if (currentParent) {
      // 给当前标签添加父级
       element.parent = currentParent 
      // 给父级添加子元素
      currentParent.children.push(element)
      // 这些属性都是我们AST树需要的基本属性
   }
   
}

// 处理文字的chars

  // 文本标签
  function chars(text) {
    // 首先需要对文本进行去空格
    text = text.trim()
    if (text.length>0) { // 去过去掉空格 还不是空的情况
       currentParent.children.push({
        type: 3,
        text
       })
    }
  }

其实这里比较那里的就是start方法里押入标签和end方法里拿出数组的最后一个标签,可以想想一下,我们start方法把(示例html模版)的前三个开始标签都压入到stack占中,在结束标签标签是我们遍历的拿到的第一个闭合结束标签肯定是,而我们stack数组里的 内容是[div,span,a],我们pop数组的也是a标签,正好是一对,然后在对当前的a标签添加parent,和给currentParent添加子集,可以好好想一下

我们的AST基本就是处理完了,我们来看一下打印出的数据

vue2.png

基本上和vue2 打印出的模版差不多了,如果大家想要源码可以留言