vue源码解读(0)
前言
小白最近也被vue源码折腾的头疼不已,小白打算把自己学习vue源码的思路说出来,如有错误的地方,请务必留言指正,让小白能在前端的道路上更进一步。如果喜欢、批评、指正、或者你有更多的想法,不妨点个,或者评论留言谢谢?。
本系列基于vue2.0.0 探讨
接下来写多少章说实话小白自己也不是很清楚,小白也不是完全学明白了然后过来给大家描述,在这里只是记录了一些小白学习的过程。最近这些天一直想着看源码,结合网上的一些文章,发现根本看不懂啊。比如说Object.defineProperty()、Mixin模式、flow.js此处省略1万字。。。。看了半天还是云里雾里。我觉得想完完全全看懂源码,首先得知道一些扩充的知识,先把这些知识补充上吧。不过今天想说的并不是跟上面那些有关的,我觉得在看源码之前应该先了解一下vue具体运行过程,它到底是怎么样来执行的。
参考了掘金小册
内部运行机制
大家应该都有印象吧,没印象的看这里哈,看下面代码:
var app = new Vue({ el: '#app', data: { message: 'Hello Vue!' }})复制代码
new Vue()之后,我们究竟做了什么?
1.初始化
在new Vue()之后,会调用_init()函数进行初始化,它会初始化生命周期、事件、 props、 methods、 data、 computed 与 watch 等。当中最重要的是通过上面咋们这个看不懂的方法**Object.defineProperty()**设置 setter 与 getter 函数,我个人理解哈,字面意思 getter就是获取,setter就是设置(修改)。这里先不说哈,继续往下。
2.挂载组件
调用$mount挂载组件(虽然这里我也没有看懂哈) 原话是这样的:
初始化之后调用 $mount 会挂载组件,如果是运行时编译,即不存在 render function 但是存在 template 的情况,需要进行「编译」步骤。
3.编译
编译可以分成三个阶段
- parse(解析)
- optimize(优化)
- generate(生成、形成) 经过这三个阶段,我们就形成了最终需要得到 render function。
parse(解析)
parse(解析)会使用正则等一些方式来解析template模版中的一些指令、样式、class啦等等一些东西来生成AST(抽象语法树) 到这里为止,我们开拓一下抽象语法树,,(虽然还没有写(滑稽),就链接到百度啦,后面会用专门的文章来了解抽象语法树是个啥东西。)
optimize(优化)
optimize(优化) 听这个名字就知道啊,肯定是用来做优化的。想一想哈,我是这么想的在vue中肯定不是所有的内容都是需要更新的,如果所有的一些东西都是要重新更新渲染的话岂不是相当于又new vue()了一遍,它的主要功能就是标记静态的节点,当我们修改data时,会触发update()更新界面,会有一个 patch 的过程,diff算法会跳过所有的静态节点,从而减少了比较的过程,优化性能。
generate(生成、形成)
generate 是将 AST 转化成 render function 字符串的过程,得到结果是 render 的字符串以及 staticRenderFns 字符串。
将抽象语法树(AST)转成字符串,供render去渲染DOM 在经历过这三个阶段后,就有我们的render function啦。就可以进行vue最核心的部分响应式。
4.响应式
我们在_init()初始化的时候通过Object.defineProperty对data数据进行了初始化,当读取的时候执行getter,当设置(修改)的时候执行setter 在进行render function被渲染的时候,会对data对象进行数据读取,会触发getter函数,从而把data里面的属性进行依赖收集,依赖收集(这个我们后面再进行分析哈,虽然我也不太懂这个词到底代表了什么),它的目的是将这些属性放到观察者(Watcher)的观察队列中,一旦我们对data里面的属性进行修改时,就会触发setter函数,setter告诉观察者数据变化,需要重新渲染视图,观察者调用update来更新视图
5.Virtual DOM
render function 会被转化成 VNode 节点。Virtual DOM 其实就是一棵以 JavaScript 对象( VNode 节点)作为基础的树,用对象属性来描述节点,实际上它只是一层对真实 DOM 的抽象。最终可以通过一系列操作使这棵树映射到真实环境上。由于 Virtual DOM 是以 JavaScript 对象为基础而不依赖真实平台环境,所以使它具有了跨平台的能力,比如说浏览器平台、Weex、Node 等。
render function 会被转化成一个虚拟的DOM,它的本质是一个js对象,大家可以理解为就是真实dom转成了用js来表示。
真实DOM:
复制代码xxxx
Virtual DOM:大概是张这样子的(只是一个简单的表示方法,实际的Virtual DOM比这个要复杂的多)
{ // tag: 'div', children: [ { tag: 'p', text: 'xxxx' } ]}复制代码
6.更新视图
当我们修改一个值的时候 会进过setter -> Watcher(观察者) -> update(更新)大致是这样一个步骤。
当修改一个值,值发生变化之后,执行 render function 得到一个新的VNode节点(其实我们就是说的那个Virtual DOM),然后把这个虚拟的DOM变成真实的DOM就完成啦。
但是这么做貌似有一些浪费,我们在前面也已经说明了,在update时我们又一个patch的步骤,在这里,我们会将旧的VNode节点跟新的VNode节点传入patch进行比较,经过diff算法我们前面貌似提过一嘴这个东西。最后,我们将比较后不相同的对应DOM进行修改即可。
以上就是小白对vue源码的一些见解,如有不对的地方,请务必提出,帮助小白来进行提升吧!