vue响应式原理-给对象添加新属性界面不刷新

vue响应式原理-给对象添加新属性界面不刷新

在这里插入图片描述

一.直接添加属性的问题

在一个VUE组件里面我们定义一个p标签,通v-for指令循环遍历Data里的item对象。然后给botton标签绑定点击事件,我们预期点击按钮时,数据新增一个属性,界面也新增一行

<p v-for="(value,key) in item" :key="key">{{ value }}</p>
<button @click="addProperty">动态添加新属性</button>
methods: {
	addProperty(){
		this.item.newProperty="新属性"  // 为item添加新属性
		console.log(this.item)  // 输出带有newProperty的items
	}
},

如下图所示点击按钮之后,发现结果不及预期,数据虽然更新了(console打印出了新属性),但页面并没有更新
在这里插入图片描述

二.原理分析

为什么会产生上面的情况呢?
vue2.0是用过Object.defineProperty实现数据响应式

const obj = {}
Object.defineProperty(obj, 'foo', {
     get() {
         console.log(`get foo:${val}`);
         return val
     },
     set(newVal) {
         if (newVal !== val) {
             console.log(`set foo:${newVal}`);
             val = newVal
         }
     }
 })
}

当我们访问foo属性或者设置foo值的时候都能够触发setter与getter,但是我们为obj添加。新属性的时候,却无法触发事件属性的拦截。原因是一开始obj的属性都被被设成了响应式数据,而后面新增的属性,并没有通过Object.defineProperty设置成响应式数据

三.解决方案

Vue 不允许在已经创建的实例上动态添加新的响应式属性
若想实现数据与视图同步更新,可采取下面常用两种解决方案:

  • Vue.set()
  • Object.assign()

Vue.set()

Vue.set( target, propertyName/index, value ),通过Vue.set向响应式对象中添加一个property,并确保这个新 property同样是响应式的,且触发视图更新

Object.assign()

直接使用Object.assign()添加到对象的新属性不会触发更新,应创建一个新的对象,合并原对象和混入对象的属性

this.someObject = Object.assign({},this.someObject,{newProperty1:1,newProperty2:2 ...})

小结

  • 如果为对象添加少量的新属性,可以直接采用Vue.set()
  • 如果需要为新对象添加大量的新属性,则通过Object.assign()创建新对象
  • 如果你需要进行强制刷新时,可采取$forceUpdate() (不建议)
  • 如果是数组也可以使用数组的方法进行添加,push,unshift,但其实底层原理也是使用了set方法。
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值