vue的双向数据绑定?动态给vue的data添加一个新的属性会发生什么?怎么解决?Object.defineProperty和proxy的对比?

60 篇文章 0 订阅
22 篇文章 0 订阅

一、什么是双向数据绑定?双向绑定是什么意思?

Model层数据改变时会驱动view层视图改变,view层视图被改变时,会影响到model层的数据。
(重点在于ViewModel:数据变化后更新视图,视图变化后更新数据)

二、MVVM双向绑定的实现?(vue2)

核心:Object.defineProperty数据劫持+发布订阅者模式

说法1:
双向数据绑定是通过数据劫持+发布订阅者模式来实现的。通过Object.defineProperty来劫持各个属性的getter/setter,
在数据变动时发布消息给订阅者,触发相应的监听回调来渲染视图。

说法2
数据劫持:vue利用Object.defineProperty创建一个observe,针对每一
个属性加一个setter/getter,一旦被重新设置会触发setter方法,setter方
法会将与之相关联的dom元素相关联的事件全部更新一遍。
发布订阅就是一种设计模式,因为每个值的变化需要更新所有的dom元
素。
如何将dom元素和设计模式关联起来:for循环把所有的dom元素遍历一
遍,如果里面含有v-指令,说明和vue相关,创建一个对象,把它放到
里面。

四、动态给vue的data添加一个新的属性会发生什么?

数据更新了,但是页面视图没有及时更新;
原因是vue2通过Object.defineProperty实现数据响应式,当访问obj.foo或设置obj.foo=‘new’时触
发setter和getter,
但是当给obj新增属性 obj.bar = ‘新属性‘时,无法触发事件属性的拦截

五、怎么解决?

由于vue不允许在已经创建的实例上动态添加新的响应式属性:
1.vue.set()
2.Object.assign()  直接使用object.assign()添加到对象的新属性不会触发更新,应创建一个新对
象,合并原对象和混入的对象
3.$forceUpdate 强制重新渲染

PS:vue3是使用proxy实现响应式数据的,直接动态新增属性仍可以实现数据响应式

六、Object.defineProperty和proxy的对比:

1.object.defineProperty只能劫持对象的属性,proxy直接代理对象
2.object.defineProperty对新增属性需要手动observe,由于object.defineProperty劫持的是对象
的属性,所以新增属性时,需要重新遍历对象,对其新增属性再使用object.defineProperty进行
劫持;因此此时需要vue.$set才能保证新增属性是响应式的;
3.proxy支持13种拦截操作,object.defineProperty不具备
4.proxy作为新标准,js引擎会继续优化,但是getter和setter基本不会
5.proxy兼容性差,目前没有一个完整支持proxy所有拦截方法的polyfill方案
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值