-
Notifications
You must be signed in to change notification settings - Fork 2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Vue.js源码阅读 #16
Comments
在大部分时间里,我们使用vue.js,几乎必然都是在使用vue的模版功能; vue 的模版简单易用,但是由于有些开发者不能完全知晓内部的处理逻辑,会显得有点“黑魔法”, 在开始阅读compile这部分的源码之前,首先我们想知道的是:vue的compile部分,在vue实例化过程中,起着怎样的作用? 在vue实例创建完成以后(created后),首先会检测有没有el选项,有的话就把对应的outerHTML取出来, 在上图,我们可以清晰地看到:compile发生在created和mounted的时间点之前,那问题来了,在这个阶段,一个Vue实例到底经历了什么? (首先,我们必须先确定正在讨论的问题,因为vue2以及vue1的compile阶段,差别较大;所以在本文,我们只讨论vue2的compile阶段) compile部分文件结构以及对应作用如下: compile 在compile这个过程里,框架主要做了三件事: 结束这三个过程以后,我们得到了render function(渲染函数);render function会渲染出VNODE(也就是virtual dom的节点) 附上一张compile/index.js里的compile函数调用图: (在vue.js 2.4里,作者在部分函数里使用typescript,以上的typescript其实很好懂:typescript需要对函数的参数,以及函数的返回值,定义类型; 简而言之,creatCompilerCreator函数接受baseCompile函数为参数,而后者又调用了parse/optimize函数/generate函数; 这一流程简单的图示如下: 解说版: v-text指令经过parse里面的html parser,htmlparser读到了 & ,于是调用了parser里的start和end方法,这两个方法,生成了一个astelement,这个astelement里面有directive这个属性,里面有v-text这个指令作为属性名以及对应的值; 然后在经过optimize这一阶段,这个astelement被标记成static(静态的) 最后经过codegen,这个astelement被输出成staticrenderfn(静态渲染函数) 然后这个static render function会渲染出一个虚拟dom节点,也就是VNODE这种数据结构,最后virtual dom tree会和之前的virtual dom tree进行diff,把diff的结果patch到实际的dom节点上,完成了下图过程。 |
parser,也叫解释器,在vue.js里,parser所做的事情很简单,就是把模版里层层嵌套的dom结构,转换成一个parent属性为空,而有children属性的的ASTElement,这个ASTElement,vue里边把它命名为根(root)。 (ast,也就是我们常说的,抽象语法树,后文提到的ASTElement,ASTExpression,ASTText,都是抽象语法树上面的节点,上文提到的root,就是一个ASTElement。) 由于parser在最后,只会返回一个ASTElement,如上文提到的那样,这个ASTElement叫做root,它的parent属性为空,只有child属性。 过程简介 就如我们第一章讲的那样: 为了说明这个过程,笔者在此以下面的模版作为例子: 对于这个模版,parser做了以下的几步: 第一步:parser调用html parser(一个开源的html解释器,作者是John Resig),并且给html parser传入四个函数,分别start() end() chars() comment(); 这个parser在于遇到开始标签的时候,举个例子: ,他就会调用一个对应的函数start(),这个函数(vue作者定制)会生成一个ASTElement,记录节点 tagName, attributes 等信息; 这个parser在遇到开始标签和结束标签之间的内容时候,就会调用一个方法char(); 在遇到注释时,会调用对应的comment()函数; 了解这四个函数,是理解其生成的三种ast节点的关键; ASTNode 上文提及到的四个函数,直接生成了三种ast节点,这三种ast类型如下: -ASTElement 对应地看一下 Vue 2.0 源码中 AST 数据结构 的定义: 注意:为了避免文章过长,我在以上的代码中注释了 ASTElement 中的许多属性,点击上方 AST 数据结构的链接可查看完整代码。 img ASTExpression & ASTText function name & function involved ASTElement & VUE指令编译优先级 只要在调用char()方法的时候,vuejs才会生成astelement以及astexpression,否则都是生成astelement 2.convert node to ast 理解ast的三种类型 编译的优先级 为什么会出现编译优先级的问题 区分更改代码/重新销毁/在使用中我们只更改数据 说说function调用判断逻辑 |
No description provided.
The text was updated successfully, but these errors were encountered: