Vue 2源码解析HTMLParserOptions.start函数方法

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

HTMLParserOptions.start()

用来解析标签的开始部分(匹配到标签开始部分时调用),主要区分标签类型、解析标签指令配置与动态绑定参数等等。

let root
let currentParent
function start(tag, attrs, unary, start, end) {
  const ns = (currentParent && currentParent.ns) || platformGetTagNamespace(tag)
  if (isIE && ns === 'svg') attrs = guardIESVGBug(attrs)
  let element: ASTElement = createASTElement(tag, attrs, currentParent)
  if (ns) element.ns = ns
  if (__DEV__) {
    if (options.outputSourceRange) {
      element.start = start
      element.end = end
      element.rawAttrsMap = element.attrsList.reduce((cumulated, attr) ={
        cumulated[attr.name] = attr
        return cumulated
      }, {})
    }
    attrs.forEach(attr =invalidAttributeRE.test(attr.name) && warn(''))
  }
  if (isForbiddenTag(element) && !isServerRendering()) {
    element.forbidden = true
    __DEV__ && warn('')
  }
  for (let i = 0; i < preTransforms.length; i++) {
    element = preTransforms[i](element, options) || element
  }
  if (!inVPre) {
    processPre(element)
    if (element.pre) inVPre = true
  }
  if (platformIsPreTag(element.tag)) inPre = true
  if (inVPre) processRawAttrs(element)
  else if (!element.processed) {
    processFor(element)
    processIf(element)
    processOnce(element)
  }
  if (!root) {
    root = element
    if (__DEV__) checkRootConstraints(root)
  }
  if (!unary) {
    currentParent = element
    stack.push(element)
  } else {
    closeElement(element)
  }
},

start 函数在解析完标签的开始部分后被调用,接收的五个参数分别是:标签名 tag,标签的属性数组 attrs,是否自闭合 unary,起点位置 start,结束位置 end

  • 进入函数之后,首先会验证 当前元素的父元素的标签命名空间(svg,math或者undefined),如果是 svg 元素,还会对解析出来的 attrs 对象进行处理,去掉 svg 标签定义属性(xmlns 之类的属性)
  • 调用 createASTElement(tag, attrs, currentParent) 方法创建当前元素对应的 AST 对象 element。此时结构如下:
{
  type: 1,
  tag: tag,
  attrsList: attrs,
  attrsMap: makeAttrsMap(attrs),
  rawAttrsMap: {},
  parent: currentParent,
  children: []
}
  • 在开发环境下,还会将节点在字符串中的位置与节点原有的属性进行记录,并且 校验属性名 是否合法(禁止空格,引号,尖括号,反斜杠和等号)
  • 校验标签合法性,如果是 style,script 之类的标签会被标记为“被禁止”(element.forbidden = true
  • 遍历 preTransforms 数组配置的处理函数,分别处理当前节点的 ast 结果,并重新更新节点的 ast 对象(这里只处理 input)

处理后的 input ast element

这里处理后的 input ast element,会比基础的 ast element 要多一些属性:

{
attrs: [],
attrsList: [],
attrsMap: { 'v-model': 'xxx' },
chidlren: [],
derectives: [{ isDynamicArg: false, modifiers: undefined, name: 'model', rawName: 'model', value: 'xxx' }],
events: {
 input: { dynamic: undefined, value: "if($event.target.composing)return;xxx=$event.target.value" }
},
hasBindings: true,
parent: currentParent,
plain: false,
props: [{ dynamic: undefined, name: 'value', value: '(xxx)' }],
rawAttrsMap: {},
static: false
}

虽然上面也省略了几个属性和部分属性值,但是重点属性都在里面。在 preTransforms 过程中,实际上是通过 preTransformNode() 函数处理 input 标签,并且该标签具有 v-model 配置,没有 v-model 时直接退出。

之后会判断该元素是否有动态绑定类型,如果是 动态绑定的元素类型,则会增加一个 ifConditions 配置,内部会填充 checkbox, radio 和 其他 input 类型的标签,用来根据不同的情况显示不同的展示形式(个人理解这里为什么只有三种,是因为 checkbox 和 radio 与其他的 input 输入框差别比较大,而且需要 label 标签配合)

  • 判断元素有没有设置 v-pre 指令或者是一个 pre 标签,重新设置 inVPre, inPre 的状态
  • 如果此时 inVPre === true,则直接跳过这个节点内部的编译;否则会依次判断 v-for,v-if 和 v-once 配置并进行编译

这里会先判断 for 循环再判断 if 条件,所以才有 for 的优先级高于 if。

如果存在 v-for,会在 ast 对象中添加 forforProcessed 属性,并解析条件;如果内部有文本节点要显示循环的值,则会在标签最末级创建一个文本节点并绑定显示条件

如果存在 v-if,会在 ast 对象中添加 ififProcessed 属性,并添加一个 ifConditions 属性,存放不同条件下的 ast 节点对象和渲染条件

如果有 v-once,一样会在 ast 对象中添加 onceonceProcessed,并且会标记 staticProcessed

  • 上面的过程执行完之后,如果此时外部的 root 是 undefined,则会将当前的节点作为根元素赋值给 root,并调用 checkRootConstraints 检查根节点
  • 如果当前节点是一个自闭合标签,则直接调用 closeElement 结束该节点;不然则将该节点赋值给 currentParent 并插入 stack 解析栈,以供子节点的解析

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

相关文章

  • vue实现全选和反选功能

    vue实现全选和反选功能

    这篇文章主要为大家详细介绍了vue实现全选和反选功能,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-08-08
  • vue-quill-editor插入图片路径太长问题解决方法

    vue-quill-editor插入图片路径太长问题解决方法

    这篇文章主要介绍了vue-quill-editor插入图片路径太长问题解决方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-01-01
  • 在vue中实现清除echarts上次保留的数据(亲测有效)

    在vue中实现清除echarts上次保留的数据(亲测有效)

    这篇文章主要介绍了在vue中实现清除echarts上次保留的数据(亲测有效),具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-09-09
  • vue3响应式转换常用API操作示例代码

    vue3响应式转换常用API操作示例代码

    在Vue 3中,响应式系统得到了显著改善,包括使用Composition API时更加灵活的状态管理,这篇文章主要介绍了vue3响应式转换常用API操作示例代码,需要的朋友可以参考下
    2024-08-08
  • 详解Vue3-pinia状态管理

    详解Vue3-pinia状态管理

    这篇文章主要介绍了Vue3-pinia状态管理,pinia是 vue3 新的状态管理工具,简单来说相当于之前 vuex,它去掉了 Mutations 但是也是支持 vue2 的,需要的朋友可以参考下
    2022-08-08
  • Vue 3.0如何配置TypeScript支持(推荐)

    Vue 3.0如何配置TypeScript支持(推荐)

    随着应用的增长,静态类型系统可以帮助防止许多潜在的运行时错误,这就是为什么Vue 3是用TypeScript编写的,本文给大家介绍Vue 3.0如何配置TypeScript支持,感兴趣的朋友一起看看吧
    2023-12-12
  • vue项目中onscroll的坑及解决

    vue项目中onscroll的坑及解决

    这篇文章主要介绍了vue项目中onscroll的坑及解决方案,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-03-03
  • 详解用vue.js和laravel实现微信授权登陆

    详解用vue.js和laravel实现微信授权登陆

    本篇文章主要介绍了详解用vue.js和laravel实现微信授权登陆,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-06-06
  • Vue实现Dialog封装

    Vue实现Dialog封装

    在写业务的时候很常见的一个场景就是需要在不同的页面调用同一个表单,常用的交互就是把表单以弹窗的形式展示,本文主要介绍了Vue实现Dialog封装,感兴趣的可以了解一下
    2021-07-07
  • vue项目中的.env文件加载方式

    vue项目中的.env文件加载方式

    在Vue项目中,通过.env文件配置环境变量,支持不同环境下加载不同配置,Vite通过import.meta.env向应用暴露环境变量,支持基本URL、开发环境和生产环境识别等,.env文件可设置环境优先级,修改后需重启生效,TypeScript可通过增加文件获取智能提示
    2024-10-10

最新评论