关于前端:Vue响应式原理概述

38次阅读

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

1 MVVM 模式

Model-View-ViewModel 源自 MVC 模式,外围是 ViewModel,ViewModel 作为一个“中转站”,对接 Model 层取得并转换数据使得数据易治理、便于 View 层应用,又对接 View 层进行双向的数据绑定。MVVM 框架利用 ViewModel 这一层帮忙开发者们做好了之前 jQuery 时代低效的查找、操作 DOM 的工作。View 最终展示的不仅是 Model 的数据,也是通过 ViewModel 加工后数据。

“ 尽管没有齐全遵循 MVVM 模型,然而 Vue 的设计也受到了它的启发。因而在文档中常常会应用 vm (ViewModel 的缩写) 这个变量名示意组件实例 ”

2 Vue 双向数据绑定

从设计思维来说,Vue 采纳的 MVVM 模式是双向绑定的。Vue 实例即充当 MVVM 中 ViewModel 层,Model 驱动 View 更新,View 层模板进行编译后 Vue 实例外部数据也会更新。从开发者应用的角度来说,Vue 并没有提供相似 AngularJS 双向数据绑定的 API。尽管它通过提供 v -model 这个语法糖提供了局部双向数据绑定的能力。Vue 实际上是单向的数据驱动视图。

<input v-model="inputData" /> 

等价于

<input :value="inputData"  @input="inputData = $event.target.value"/>

3 数据驱动视图

视图是由数据驱动生成的,对视图的批改,不是间接操作 DOM 而是通过批改数据。通过利用 虚构 DOM,Vue 实现了数据驱动视图。整体看一下从创立 Vue 实例到最初渲染到页面产生的过程。如图:

数据驱动生成视图的过程:

1)初始化 Vue:Vue 是一个类,new Vue({…})操作调用构造函数实现合并配置、初始化生命周期、事件核心,初始化 Injections、state(props|data|methods|computed|watch)、provide 等;
2)挂载 Vue 实例到 el:校验页面上的挂载点 el, 并拿到对应的 template;
3)模板编译 :由 template 编译出 render() 函数,通过一系列的 compileToFunctions-createCompiler-createCompilerCreator 后,最初 Parse 出 ast,通过优化 ast,最终生成 render 代码;
4)调用 render():将自定义配置中的数据和页面模板生成的数据联合后,生成 VDOM;
5)update 和 patch上一步的 VDOM 出 DOM:patch 提供了钩子函数,在回调中做相应的解决生成 DOM。

4 响应式原理

响应式原理指的是 Vue 中数据变动驱动视图更新。实现的要害两个点:

1)将数据变成 响应式数据
2)实现一个 观察者模式:进行依赖收集和派发更新。

响应式数据是指 通过代理对象的形式给数据增加上 getter、setter 属性个性,从而使对数据的拜访、更新操作是可观测的 。Vue2 应用 Object.defineProperty() 办法,Vue3 应用的是 Proxy 对象。再通过观察者模式,在拜访数据时进行依赖的收集,在数据更新时派发告诉给之前收集到的依赖做更新解决。具体来说,在 Vue 外部,通过 Observer 类将数据递归地转化成可观测对象,最终生成的响应式数据对象,是一个蕴含了__ob__属性的对象。在其外部定义、并调用了一系列处理函数:如 walk()\defineReactive()。


依赖收集 :产生在拜访响应式数据触发 getter 函数时,收集的 依赖指的是渲染 Watcher,收集动作的主体即为响应式数据自身。具体来说 Vue 外部实现了一个治理 Watcher 的 Dep 类(外部保护了一个数组),每个响应式数据对象属性值的 getter 都持有一个 dep 的援用。当实现一次 render 调用后,会触发所有响应式数据的 getter,从而实现响应式数据 Watcher 的收集的过程。


派发更新 :产生在更新响应式数据触发 setter 函数时,实际上就是把之前收集好的 Watcher 依赖从队列中取出来执行其 update() 办法的过程。其中 Vue 也做了一些优化,并不会每次数据扭转都触发 watcher 的回调执行,而是把这些 watcher 先增加到一个队列里,而后在 nextTick 后执行 flushSchedulerQueue,利用 JavaScript 提供的事件队列的这种异步的形式执行更新动作。

5 Vue2 和 Vue3 响应式原理的区别

Vue2 应用 Object.defineProperty(),Vue3 应用的是 Proxy。相比 Object.defineProperty(),Proxy()不仅能够解决 无奈观测对象新增删除属性、无奈观测数组通过索引设值、长度变动的问题 ,其 API 更为丰盛。比照 Object.defineProperty() 观测对象的属性,Proxy 代理的是对象,性能也更好。
Object.defineProperty()之所以不反对数组,是因为 Vue 基于性能思考没有用,而不是因为它不反对。

参考:
Vue 技术揭秘

https://ustbhuangyi.github.io…
https://www.cnblogs.com/iovec…

正文完
 0