Vue源码解析:模板编译Parse(一)

源码分析通常都是从入口开始慢慢分析,这次将直接开始分析核心,然后由内而外找到代码源头。更加符合分析时候的思路。

解析的核心就是parseHTML函数:利用while循环和正则表达式对template的字符串模板逐字符解析。

Vue模板解析的时候对script/style/textarea这个三个标签做了特殊处理。所有,大体上,编译字符串标签分成两类

非script/style/textarea标签

textEnd = html.index("<"),利用textEnd这个变量来区分节点是否为文本节点。

文本节点

1<2
,因为文本节点内也可以使用<符号,但是这个符号并不代表一个标签

其他元素节点

    ,ul标签内部为空没有文本,没有<符号

    1. 注释节点

    2.  条件注释节点

    http://en.wikipedia.org/wiki/Conditional_comment#Downlevel-revealed_conditional_comment

    3. <!DOCTYPE>标签

    4. 结束标签

    advance函数:index为当前的解析位置,每次解析完都要截取html字符串,直至html解析完为空字符串,while循环终止

    parseEnd函数:endTagMatch[1]为当前标签名称,curIndex为闭合标签字符串的其实位置,index为闭合标签字符串的结束位置(advance中已经对index做出了改变)。

    利用stack存储解析中的标签,例如模板为

    ,在解析的時候,stack为[div, ul, li]。pos为当前li标签在stack中的位置,如果位置不一样,说明标签没有闭合,vue在非生产环境下会提示。

    然后调用end函数来生成AST节点。

    5. 开始标签

    handleStartTag函数:利用attribute/dynamicAttribute正则来解析属性及其值,然后将标签入栈。

    另外,由于标签可能是自闭合标签,如
    ,此类标签是不需要入栈的。

    随后,将lastTag更新为此时正在解析的标签。

    最后,调用start函数来生成AST节点。

    6. 文本元素

    解析文本元素的时候要考虑到文本元素中存在<符号。考虑到标签开始/结尾/注释节点/条件注释节点都有<符号,因此在不满足以上条件的正则时,文本会一直解析下去。

    最后调用chars函数处理文本节点。

    script/style/textarea标签

    对于这三个元素,模板解析的时候会把这些元素内的所有内容都当成字符串来处理。并且利用replace函数处理了里面部分字符串,然后调用了chars函数。

    最后依然是更新index与html,并处理父元素闭合标签。具体见注释。

    html=last

    parseEndTag()

    利用不传参的parseEndTag函数来清空内部栈。

    最后

    其实Vue模板编译部分看似很长,其实没有什么东西。

    真正的精髓是

    1. 书写正确的正则表达式

    2. 利用栈结构来保证标签解析正确与否

    3. 利用while循环

    另外,文章一开始的parseHTML中就有template与options参数,template就是我们书写的模板字符串,options包含了很多,其中就有解析开始标签/结束标签/文本节点时调用的options.start/end/chars,下文将解析这部分内容,分析Vue如何将解析得到的字符转化成AST节点。

    原文链接:juejin.im

    上一篇:矩阵链相乘
    下一篇:让你30分钟快速掌握vue 3

    相关推荐

    • 🚩Vue源码——订阅者的响应

      前言 在上篇专栏中介绍了发布者是如何收集订阅者(Watcher),本专栏来详细介绍发布者发生变化后,如何通知订阅者,而订阅者是如何响应。 一、如何通知订阅者 在 Vue 中发布者一般是数据,当数据发生...

      23 天前
    • 🚩Vue源码——组件是如何注册的

      最近参加了很多场面试,几乎每场面试中都会问到Vue源码方面的问题。在此开一个系列的专栏,来总结一下这方面的经验,如果觉得对您有帮助的,不妨点个赞支持一下呗。 前言 在上一篇 🚩Vue源码——组件...

      2 个月前
    • 🚩Vue源码——组件如何渲染成最终的DOM

      最近参加了很多场面试,几乎每场面试中都会问到Vue源码方面的问题。在此开一个系列的专栏,来总结一下这方面的经验,如果觉得对您有帮助的,不妨点个赞支持一下呗。 前言 Vue有两个核心思想,一个是数据...

      2 个月前
    • 🚩Vue源码——如何监听数据变化

      最近参加了很多场面试,几乎每场面试中都会问到Vue源码方面的问题。在此开一个系列的专栏,来总结一下这方面的经验,如果觉得对您有帮助的,不妨点个赞支持一下呗。 前言 Vue 是用数据来驱动来生成视图...

      1 个月前
    • 🚩Vue源码——如何深度收集渲染订阅者

      前言 本专栏是由一个问题引起,如果你已经知道答案了,可以忽略本专栏。 &lt;!DOCTYPE html&gt; &lt;html&gt; &lt;head&gt; &...

      11 天前
    • 🚩Vue源码——nextTick实现原理

      前言 在上一篇专栏讲到订阅者的响应是先把订阅者添加到一个队列,然后再 nextTick 函数中去遍历这个队列,对每个订阅者进行响应处理。大家所熟悉的 Vue API Vue.nextTick 全局方法...

      19 天前
    • 🔥手写大厂前端知识点源码系列(上)

      如今前端攻城狮的要求越来越高,会使用常见的API已经不能满足现如今前端日益快速发展的脚步。现在大厂基本都会要求面试者手写前端常见API的原理,以此来证明你对该知识点的理解程度。

      8 个月前
    • 🔥前端面试大厂手写源码系列(上)

      如今前端攻城狮的要求越来越高,会使用常见的API已经不能满足现如今前端日益快速发展的脚步。现在大厂基本都会要求面试者手写前端常见API的原理,以此来证明你对该知识点的理解程度。

      8 个月前
    • (源码分析)为什么 Vue 中 template 有且只能一个 root ?

      引言 今年,疫情并没有影响到各种面经的正常出现,可谓是络绎不绝(学不动...)。然后,在前段时间也看到一个这样的关于 Vue 的问题,为什么每个组件 template 中有且只能一个 root? 可能...

      7 个月前
    • 面试还问redux?那我从头手撸源码吧(中间件篇)

      昨天的文章手写了一版redux的核心源码,redux库除了数据的状态管理还有一块重要的内容那就是中间件,今天我还是尝试将此部分源码完成。 中间件 react中管理数据的流程是单向的,就是说,从派发动作...

      2 年前

    官方社区

    扫码加入 JavaScript 社区