Vue 2源码解析ParseHTML函数HTML模板

 更新时间:2022年08月15日 11:04:15   作者:MiyueFE  
这篇文章主要为大家介绍了Vue 2源码解析ParseHTML函数HTML模板详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

ParseHTML函数 - HTML 模板解析

之前在解析 parse 函数时,我们知道整个 解析 template 模板并生成 ast 对象 的过程都发生在这个函数的执行过程中。

但是 parse 函数内部本身只定义了一些标签、指令的处理方法和警告函数,并且在传递给 parseHTML 函数的参数中定义了四个处理方法。

最终是通过调用 parseHTML 来解析 template 模板

整个解析过程,其实就是 通过一系列正则表达式来匹配 template 模板字符串,并截取该部分匹配内容并重新匹配剩余部分,直到全部匹配完成。

所有的正则表达式包含以下内容:

const attribute = /^\s*([^\s"'<>\/=]+)(?:\s*(=)\s*(?:"([^"]*)"+|'([^']*)'+|([^\s"'=<>`]+)))?/  // 静态属性解析
const dynamicArgAttribute = /^\s*((?:v-[\w-]+:|@|:|#)\[[^=]+?\][^\s"'<>\/=]*)(?:\s*(=)\s*(?:"([^"]*)"+|'([^']*)'+|([^\s"'=<>`]+)))?/ // 动态属性解析(含有 v-xxx:, :, @, # 的属性)
const ncname = `[a-zA-Z_][\\-\\.0-9_a-zA-Z${unicodeRegExp.source}]*`
const qnameCapture = `((?:${ncname}\\:)?${ncname})`
const startTagOpen = new RegExp(`^<${qnameCapture}`)   // 开始标签部分
const startTagClose = /^\s*(\/?)>/                     // 开始标签结束
const endTag = new RegExp(`^<\\/${qnameCapture}[^>]*>`)// 结束标签部分
const doctype = /^<!DOCTYPE [^>]+>/i                   // DOCTYPE 声明
const comment = /^<!\--/                               // 注释部分
const conditionalComment = /^<!\[/                     // 条件注释

parseHTML 的简要代码如下:

export function parseHTML(html, options: HTMLParserOptions) {
  const stack: any[] = []
  const expectHTML = options.expectHTML
  const isUnaryTag = options.isUnaryTag || no
  const canBeLeftOpenTag = options.canBeLeftOpenTag || no
  let index = 0
  let last, lastTag
  while (html) {
    last = html
    if (!lastTag || !isPlainTextElement(lastTag)) {
      let textEnd = html.indexOf('<')
      if (textEnd === 0) {
        if (comment.test(html)) {
          // 处理 注释
          advance()
          continue
        }
        if (conditionalComment.test(html)) {
          // 处理 条件注释
          advance()
          continue
        }
        // Doctype:
        if (html.match(doctype)) {
          advance()
          continue
        }
        // 结束:
        if (html.match(endTag)) {
          advance()
          parseEndTag()
          continue
        }
        // 开始:
        if (parseStartTag()) {
          advance()
          handleStartTag()
          continue
        }
      }
      // 处理纯文本
      options.chars()
      advance()
    } else {
      // 结束
      parseEndTag()
    }
    if (html === last) {
      options.chars && options.chars(html)
      break
    }
  }
  parseEndTag()
  function advance(n) {
  }
  function parseStartTag() {
  }
  function handleStartTag(match) {
  }
  function parseEndTag(tagName?: any, start?: any, end?: any) {
  }
}

其中定义了三个标签处理方法和一个定位方法:

  • advance 方法是更新当前解析到的文本位置 index,并截取掉已解析的部分
  • parseStartTag 方法用来解析标签的开始部分,内部会生成一个包含标签名 tagName 和属性数组 attrs 的对象 math,并循环解析内部的字符串直到解析完整个字符串,将解析到的属性存放到 attrs 数组中
  • handleStartTag 则是处理 parseStartTag 得到的 math 对象(大部分是处理每个属性),如果上面解析到是非闭合标签的话,也会将这个 math 对象修改成一个新对象插入到 parseHTML 执行时定义的 stack 元素栈中;当然,如果是自闭合标签,还会调用 parseEndTag 方法处理;并在 最后调用 options 中定义的 start 函数来生成 ast 对象
  • parseEndTag 方法就用来处理标签结束后的逻辑,会根据条件清除 stack 栈中的元素;如果此时元素标签是 br 或者 p,也会调用 option.start(),其他情况下一般会调用 options.end() 来结束当前标签的解析

总的来说,parseHTML 就是通过正则表达式来匹配不同的标签和属性,进行不同的标签/属性处理,最后通过 options 中的回调函数来创建完整的 ast 对象;并用 stack 元素栈的方式来保证原始 template 模板与 ast 对象的层级结构的一致性。

以上就是Vue 2源码解析ParseHTML函数HTML模板的详细内容,更多关于Vue ParseHTML函数模板的资料请关注脚本之家其它相关文章!

相关文章

  • vue中 el-table每个单元格包含多个数据项处理

    vue中 el-table每个单元格包含多个数据项处理

    vue项目中,我们需要在el-table中显示数组数据,有的时候,需要在一个单元格中显示多条数据,如何实现呢,对vue el-table单元格相关知识感兴趣的朋友一起看看吧
    2023-11-11
  • Vue编译器optimize源码分析

    Vue编译器optimize源码分析

    这篇文章主要为大家介绍了Vue 编译器optimize源码分析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-07-07
  • vue图片上传本地预览组件使用详解

    vue图片上传本地预览组件使用详解

    这篇文章主要为大家详细介绍了vue图片上传本地预览组件,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-02-02
  • vue.js使用代理和使用Nginx来解决跨域的问题

    vue.js使用代理和使用Nginx来解决跨域的问题

    下面小编就为大家分享一篇vue.js使用代理和使用Nginx来解决跨域的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-02-02
  • vue过滤器用法实例分析

    vue过滤器用法实例分析

    这篇文章主要介绍了vue过滤器用法,结合实例形式总结分析了vue.js常见过滤器相关使用技巧与操作注意事项,需要的朋友可以参考下
    2019-03-03
  • vue实现输入框自动跳转功能

    vue实现输入框自动跳转功能

    这篇文章主要为大家详细介绍了vue实现输入框自动跳转功能,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-05-05
  • Element Plus组件Form表单Table表格二次封装的完整过程

    Element Plus组件Form表单Table表格二次封装的完整过程

    一般在后台管理系统的开发中,都会遇到很多table,但每一次都去引入el-table就会导致代码十分冗余,所以基于组件做一下二次封装成自己需要的组件就十分nice,下面这篇文章主要给大家介绍了关于Element Plus组件Form表单Table表格二次封装的相关资料,需要的朋友可以参考下
    2022-09-09
  • ElementUI之Message功能拓展详解

    ElementUI之Message功能拓展详解

    这篇文章主要介绍了ElementUI之Message功能拓展详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-10-10
  • vue.js绑定class和style样式(6)

    vue.js绑定class和style样式(6)

    这篇文章我们将一起学习vue.js实现绑定class和style样式,感兴趣的小伙伴们可以参考一下
    2016-12-12
  • vue项目中js文件使用vue的this实例说明

    vue项目中js文件使用vue的this实例说明

    这篇文章主要介绍了vue项目中js文件使用vue的this实例说明,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-12-12

最新评论