背景:使用vue进行对象赋值,如果是一个未在data声明的属性,会导致双向绑定无法正常回显。
<template> <div> <div> <label for="">姓名</label> <input v-model="info.name" type="text"> </div> <div> <label for="">年龄</label> <input v-model="info.age" type="text"> </div> <br> <div> <button @click="setAge">设置年龄</button> </div> </div> </template> <script> export default { name: "", data() { return { info: { name: '' } } }, methods: { setAge() { this.info.age = 0 } } }; </script>
原因:vue2的defineProperty是在新生成对象的时候完成双向绑定,并不能新增property和删除property的时候完成页面同步显示,会导致页面显示出现延迟。
vue提供了两个方法 $set $delete 来解决这个问题。
vm.$set( target, propertyName/index, value )
向响应式对象中添加一个 property,并确保这个新 property 同样是响应式的,且触发视图更新。它必须用于向响应式对象上添加新 property,因为 Vue 无法探测普通的新增 property (比如 this.myObject.newProperty = 'hi'
)
vm.$delete( target, propertyName/index )
对象的 property。如果对象是响应式的,确保删除能触发更新视图。这个方法主要用于避开 Vue 不能检测到 property 被删除的限制,但是你应该很少会使用它。
vm.$forceUpdate()
迫使 Vue 实例重新渲染。注意它仅仅影响实例本身和插入插槽内容的子组件,而不是所有子组件。
解决方法:
- 可以使用vue提供的$set来实现响应式,
- 建议通过展开运算符来生成一个新的响应式对象。 this.info = {...this.info, age: 10}
- 不建议使用$forceUpdate