Vue.js中如何使新增空对象具备响应式(无需预先在data中定义)
Vue 2中动态添加数组元素并使其响应式的解决方案
这个问题我之前也碰到过,Vue 2对数组和对象的响应式监测有特定的规则,直接通过索引给数组赋值this.items[0] = {}是不会被Vue监测到的,所以这个空对象自然不会成为响应式对象,后续给它加属性也无法触发视图更新。不用预先在data里定义items: [{}]的话,有两种靠谱的解决思路:
方法一:用Vue.set(或this.$set)给数组添加元素
Vue.set是Vue提供的手动触发响应式更新的API,不仅可以给对象新增响应式属性,也能用来给数组指定索引位置添加/替换元素,这样添加的元素会自动被纳入响应式系统。
修改后的代码示例:
let app = new Vue({ el: "#app", data: { items: [], }, methods: { setItems: function (newValue) { // 第一步:用Vue.set把空对象加入数组,使其成为响应式对象 Vue.set(this.items, 0, {}); // 第二步:给响应式对象新增name属性(Vue 2中对象新增属性需要用Vue.set) Vue.set(this.items[0], 'name', newValue); // 后续API更新值时,直接赋值即可(因为对象已经是响应式的了) // 比如定时更新:this.items[0].name = newUpdatedValue; } } })
如果一开始就知道要给对象加name属性,也可以一步到位,省掉第二次Vue.set:
Vue.set(this.items, 0, { name: newValue });
方法二:用数组的变异方法替换元素
Vue能自动监测数组的变异方法(比如splice、push、pop等),所以可以用splice来替换数组指定索引的元素,这样新加入的对象也会成为响应式对象。
代码示例:
let app = new Vue({ el: "#app", data: { items: [], }, methods: { setItems: function (newValue) { // 用splice替换索引0的元素(如果数组为空,splice会直接添加) this.items.splice(0, 1, {}); // 给响应式对象添加name属性 this.$set(this.items[0], 'name', newValue); // 后续更新直接赋值:this.items[0].name = newUpdatedValue; } } })
关键原理说明
Vue 2无法检测数组的以下操作:
- 通过索引直接设置元素,比如
this.items[0] = {} - 修改数组的长度,比如
this.items.length = 0
所以必须通过Vue.set或者数组变异方法来修改数组,才能让新元素成为响应式对象。当对象成为响应式后,后续修改它已有的属性(比如name)会自动触发视图更新;如果要给这个对象新增其他属性,还是需要用Vue.set来添加。
内容的提问来源于stack exchange,提问作者user15301516
相关产品推荐
相关产品推荐

