vue2和vue3数据双向绑定原理

Posted lzpDailyNotes

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了vue2和vue3数据双向绑定原理相关的知识,希望对你有一定的参考价值。

vue2数据双向绑定和vue3数据双向绑定的原理透析

参考资料 : https://www.jianshu.com/p/d7e2efde434b

https://www.jianshu.com/p/d7e2efde434b

背景:面试官10个有9个都会问这个问题,所以深究一下啦

需要提前了解的知识:

​ 1.什么是MVVM: 是一种设计思想,由模型层(M)+视图层(V)+视图模型层(VM)构成。MVVM主要通过数据劫持+发布订阅模式实现

2.MVVM的优点:

​ ① 低耦合性 view 和 model 之间没有直接的关系,通过 viewModel 来完成数据双向绑定。

​ ②可复用性 组件是可以复用的。可以把一些数据逻辑放到一个 viewModel 中,让很多 view 来重用。

​ ③独立开发 开发人员专注于 viewModel ,设计人员专注于view。

​ ④可测试性 ViewModel 的存在可以帮助开发者更好地编写测试代码。

​ ⑤不用操作大量的dom

​ 3.MVVM的缺点:

​ ①bug很难被调试,因为数据双向绑定,所以问题可能在 view 中,也可能在 model 中,要定位原始bug的位置比较难,同时view里面的代码没法调试,也添加了bug定位的难度。

​ ②一个大的模块中的 model 可能会很大,长期保存在内存中会影响性能。

​ ③对于大型的图形应用程序,视图状态越多, viewModel 的构建和维护的成本都会比较高。

​ 4.mvvm的双向绑定原理:

​ 核心就是数据劫持、数据代理、数据编译和发布订阅模式:

​ ①数据劫持-就是给对象添加get、set钩子函数

​ 1.观察对象,给对象增加Object.defineProperty

​ 2.循环递归data属性,给属性添加get、set钩子函数

​ 3.vue的特点就是新增不存在的属性不会给该属性添加get、set钩子函数

​ 4.每次赋予一个新对象时,会给这个新对象进行数据劫持(defineProperty)

​ ②数据代理:

​ 解释:将data、method、computed上的数据挂在到vm实例上

​ ③数据编译:

​ 解释:把,v-html,v-model,v-on 里面对应的变量用data里面的数据进行替换

​ ④发布订阅:

​ 主要靠的是数组关系,订阅就是放入函数,发布就是让数组里的函数执行。在get钩子函数被调用时进行数据的订阅,在set钩子函数被调用时进行数据的发布。

vue2的数据双向绑定原理:

​ 1.递归data中的值并添加Object.defineProperty()

​ 2.dep的实现

​ 3.compiler实现对vue各个指令模板的解析器,生成抽象语法树,编译成Virtual Dom,渲染视图

​ 4.第四步:Watcher 连接observer和compiler,接受每个属性变动的通知,绑定更新函数,更新视图

​ 5.完整实现代码:

defineProperty的缺点: //监听的是对象的某个属性,而非整个对象

​ 1.无法检测到对象属性的新增或删除

​ 2.不能监听数组的变化

vue3的数据双向绑定原理:

​ proxy的劣势: //监听的是整个对象

​ 1.兼容性问题

​ 2.性能差

vue2.x双向数据绑定原理

参考技术A 1.vue双向数据绑定原理

vue.js采用的是数据劫持结合发布者-订阅者模式的方式.利用Object.defineProperty来劫持对象,利用getter,setter在数据变动时发布消息给订阅者,触发相对应的监听回调,更新视图.

2.实现数据绑定的方法大致有几种

1.发布者-订阅者模式 :一般通过sub、pub的方式实现数据和视图的绑定监听,更新数据的方式通常做法是vm.set('property',value)。我们更希望通过vm.prototype=value这种方式更新视图数据,同时自动跟新视图.

2.脏值检查 :angular.js是通过脏值检测的方式对比数据是否有变更,来决定视图是否更新,最简单的方式就是通过setInterval(),定时轮询检测数据变动,应为setInterval太耗费性能,所以angular只有在指定的事件触发时进入脏值检查,大致如下:

1.DOM事件,譬如用户输入文本,点击按钮等.(ng-click)

2.XHR响应事件($http)

3.浏览器Location变更事件($location)

4.Timer事件($timeout,$interval)

5.执行$digest()或$apply()

3.数据劫持: vue.js则是采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应的监听回调.

3.vue双向数据绑定(具体流程)

实现过程

首先对数据进行劫持与监听,需要设置一个监听器Observer,用来监听所有的属性.如果属性发生了变化,会通知消息订阅器Dep(收集订阅者),Dep通知订阅者Watcher看是否需要更新.然后在监听Observer和订阅者Watcher之间统一管理,触发视图更新.同时创建一个指令解析器Compile,根据new Vue实例传入的el绑定的元素,对它的子元素进行扫描与解析,对相关指令对应初始化一个订阅者watcher存放在订阅器中(Dep),并替换模板数据或者绑定相对应的函数,如果当订阅者watcher接收到相对应属性的变化,就会执行相对应的更新函数,从而更新视图.

1.实现一个监听器Observer,用来劫持并监听所有的属性,如果有变动就通知订阅者.

2.实现一个订阅者Watcher,收到属性的变化通知并执行相对应的函数,从而更新视图.

3.实现一个解析器Compile,可以扫描和解析每个节点的相关指令,并初始化模板数据以及初始化相对应的订阅器.

下节Compile的简单实现: https://www.jianshu.com/p/6eb248664443

以上是关于vue2和vue3数据双向绑定原理的主要内容,如果未能解决你的问题,请参考以下文章

Vue双向绑定原理 从vue2的Object.defineProperty到vue3的proxy

vue2.x双向数据绑定原理

Vue3.0 双向绑定原理

Vue3 双向绑定——Proxy

关于vue的计算属性以及双向绑定的原理理解(vue2.x)以及vue3.0

vue2和vue3的区别?