vue源码解读--parse(创建ast树)

目录导航

沿用上一节的示例代码

定位断点

上一节我们说到,在解析main过程中执行handleStartTag的最后一步将会调用start函数生成ast节点,将代码定位于此,入参为:main、{attrs:{name:"id",value:"app",start:6,end:14}、false、0、15

handleStartTag

    \odot 调用createASTElement生成一个ast元素

(因此元素节点的ast节点为1)

    \odot process.env.NODE_ENV为开发环境进入判断,对attrs做一次遍历,校验其合法性,比如不能包含引号、尖括号、等号等特殊字符

    \odot isForbiddenTag(element)当前为false,对于符合其条件的代码则是对一些特殊标签作校验,如不能是style或script标签,因为这不会被解析

    \odot 调用preTransforms对v-model做特殊处理

    \odot 调用process开头的函数,process为加工,再结合for、if。可以推断出该处是对v-for等指令的处理。且处理过后,ast元素节点上会相应的添加某些标识

        由于当前的main标签不存在v-if或v-for指令,但是我们的示例中的ul存在v-if、li存在v-for。故我们分别跳到ul和li的位置。根据上一节的分析,我们知道此时的attrs的关键参数分别为{v-if:'isList'}、{v-for:'(v,i) in list'}

            \ominus processIf

                        \cong getAndRemoveAttr获取v-if的值,即isList

                        \cong 进入判断向ast元素节点上添加if属性,值为isList;并调用addIfCondition向节点添加ifConditions属性,值为数组[{exp:isList,block:ast元素节点}]

              \ominus processFor

                            \cong getAndRemoveAttr获取v-for的值,即:(v,i) in list

                            \cong parseFor解析出遍历v、i、list

                            \cong 调用extend向ast节点上添加for的标识属性:for:list,alias:v,iterator1:i

    \odot 回到start函数,向下判断当前节点是否是单标签,如果不是,则currentParent=element,并向stack中push当前的ast元素节点。那么这两步操作究竟有何用呢?(我们当前一直关注的都是开始标签的ast处理,故我们现在分析下结束标签的处理来看下是否能形成一个闭合)

parseEndTag

    \odot tagName="li",进入判断,根据之前分析,由于当前在解析的流程中故stack中保存的是main、ul、li,将在pos=2时匹配到,进入判断,调用end函数

                \oplus 拿到保存ast节点的stack,取到最后一位li。之后将stack中的最后一位pop掉,并且将currentParent指向上一位ul,后调用closeElement,将li(ast)元素传入

                            \bullet 框红的位置,向父ast节点ul的children下保存了当前的ast节点li,并让当前ast节点li的parent指向了父ast节点ul。


故,ast树的创建过程实际上是针对不同的元素类型创建不同的ast节点类型,在每一次模板标签的解析过程中会将其属性进行解析并使用约定的标识添加到ast节点上。并且ast节点之间通过children和parent来建立父子关系。最终建立起一个可以完美映射dom树的节点树

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容