vue.js框架原理浅析

42次阅读

共计 2132 个字符,预计需要花费 6 分钟才能阅读完成。

vue.js 是一个非常优秀的前端开发框架,不是我说的,大家都知道。
首先我现在的能力,独立阅读源码还是有很大压力的,所幸 vue 写的很规范,通过方法名基本可以略知一二,里面的原理不懂的地方多方面查找资料,本文中不规范不正确的地方欢迎指正,学生非常愿意接受各位前辈提出宝贵的建议和指导。
使用 vue 的版本是 v2.5.13,采用了 flow 作为类型管理工具,关于 flow 相关内容选择性忽略了,不考虑类型系统,只考虑实现原理,写下这篇文章。
本文大概涉及到 vue 几个核心的地方:vue 实例化,虚拟 DOM,模板编译过程,数据绑定。
一、vue 的生命周期

二、vue 实例化
研究 vue 的实例化就要研究_init 方法,此方法定义在 src/core/instance/init.js 下的 initMixin 中,里面是对 vue 实例即 vm 的处理。其中包括开发环境下的代理配置等一些列处理, 并处理了传递给构造函数的参数等,重点在一系列方法
initLifecycle(vm)
initEvents(vm)
initRender(vm)
callHook(vm, ‘beforeCreate’)
initInjections(vm) // resolve injections before data/props
initState(vm)
initProvide(vm) // resolve provide after data/props
callHook(vm, ‘created’)
初始化生命周期,初始化事件,初始化渲染,触发执行 beforeCreate 生命周期方法,初始化 data/props 数据监听,触发执行 created 生命周期方法。
对应到生命周期示例图,created 方法执行结束,接下来判断是否传入挂载的 el 节点,如果传入的话此时就会通过 $mount 函数把组件挂载到 DOM 上面,整个 vue 构造函数就执行完成了。以上是 vue 对象创建的基本流程。
三、模板编译
挂载的 $mount 函数,此函数的实现与运行环境有关,在此只看 web 中的实现。
实现只有简单的两行,
1、判断运行环境为浏览器,

2、调用工具方法查找到 el 对应的 DOM 节点,

3、mountComponent 方法来实现挂载,
这里就涉及到了挂载之前的处理问题。
1、对于拥有 render(JSX) 函数的情况,组件可以直接挂载,

2、如果使用的是 template,需要从中提取 AST 渲染方法(注意如果使用构建工具,最终会为我们编译成 render(JSX) 形式,所以无需担心性能问题),AST 即抽象语法树,它是对真实 DOM 结构的映射,可执行,可编译,能够把每个节点部分都编译成 vnode,组成一个有对应层次结构的 vnode 对象。
有了渲染方法,下一步就是更新 DOM,注意并不是直接更新,而是通过 vnode,于是涉及到了一个非常重要的概念。
四、虚拟 dom
虚拟 DOM 技术是一个很流行的东西,现代前端开发框架 vue 和 react 都是基于虚拟 DOM 来实现的。
虚拟 DOM 技术是为了解决一个很重要的问题:浏览器进行 DOM 操作会带来较大的开销。
1、要知道 js 本身运行速度是很快的,

2、而 js 对象又可以很准确地描述出类似 DOM 的树形结构,
基于这两点前提,人们研究出一种方式,
通过使用 js 描述出一个假的 DOM 结构,每次数据变化时候,在假的 DOM 上分析数据变化前后结构差别,找出这个最小差别并且在真实 DOM 上只更新这个最小的变化内容,这样就极大程度上降低了对 DOM 的操作带来的性能开销。
上面的假的 DOM 结构就是虚拟 DOM,比对的算法成为 diff 算法,这是实现虚拟 DOM 技术的关键。
1、在 vue 初始化时,首先用 JS 对象描述出 DOM 树的结构,

2、用这个描述树去构建真实 DOM,并实际展现到页面中,

3、一旦有数据状态变更,需要重新构建一个新的 JS 的 DOM 树,

4、对比两棵树差别,找出最小更新内容,

5、并将最小差异内容更新到真实 DOM 上。
有了虚拟 DOM,下面一个问题就是,什么时候会触发更新,接下来要介绍的,就是 vue 中最具特色的功能 – 数据响应系统及实现。
五、数据绑定
vue.js 的作者尤雨溪老师在知乎上一个回答中提到过自己创作 vue 的过程,最初就是尝试实现一个类似 angular1 的东西,发现里面对于数据处理非常不优雅,于是创造性的尝试利用 ES5 中的 Object.defineProperty 来实现数据绑定,于是就有了最初的 vue。vue 中响应式的数据处理方式是一项很有价值的东西。
vue 官网上面其实有具体介绍,下面是一张官方图片:

vue 响应
响应实现的基本原理:
1、vue 会遍历此 data 中对象所有的属性,

2、并使用 Object.defineProperty 把这些属性全部转为 getter/setter,

3、而每个组件实例都有 watcher 对象,

4、它会在组件渲染的过程中把属性记录为依赖,

5、之后当依赖项的 setter 被调用时,会通知 watcher 重新计算,从而致使它关联的组件得以更新。
为什么 vue 不能在 IE8 以下运行?
因为 IE8 不支持 ES5,所以用不了 Object.defineProperty 方法,又因为 Object.defineProperty 无法 shim,所以 vue 不支持 IE8 及以下不支持 ES5 的浏览器。

正文完
 0