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