Vue数据绑定数组,改变元素时不更新view问题
问题描述
关于这个问题,Vue官方文档上说的很清楚
由于 JavaScript 的限制,Vue 不能检测以下变动的数组:
- 当你利用索引直接设置一个项时,例如:
vm.items[indexOfItem] = newValue
- 当你修改数组的长度时,例如:
vm.items.length = newLength
举个例子:
var vm = new Vue({
data: {
items: ['a', 'b', 'c']
}
})
vm.items[1] = 'x' // 不是响应性的
vm.items.length = 2 // 不是响应性的
为了解决第一类问题,以下两种方式都可以实现和 vm.items[indexOfItem] = newValue
相同的效果,同时也将触发状态更新:
// Vue.set
Vue.set(vm.items, indexOfItem, newValue)
// Array.prototype.splice
vm.items.splice(indexOfItem, 1, newValue)
this.items = JSON.parse(JSON.stringify(this.items))
你也可以使用 vm.$set
实例方法,该方法是全局方法 Vue.set
的一个别名:
vm.$set(vm.items, indexOfItem, newValue)
为了解决第二类问题,你可以使用 splice:
vm.items.splice(newLength)
示例说明
<body>
<div class="box">
<div v-for="a in arr">{{a}}</div>
<button @click="change">刷新国家</button>
</div>
</body>
var vm = new Vue({
el: '.box',
data: {
arr: ['china', 'america', 'russia', 'europe']
},
methods: {
change () {
// 点击按钮时,改变arr的最后一个元素
// 数据变了,但是view没有更新
this.arr[3] = 'hangzhou'
}
}
})
因为Vue实现双向数据绑定的机制是数据劫持,也就是在所有对象上有个Object.defineProperty()方法,通过监听set与get方法去实现,而数组没有这两个方法,所以就不会更新view。解决方案就是,需要我们主动通知Vue。
- 解决方案1
methods: {
change () {
this.arr[3] = 'hangzhou'
// 在vm实例上通知
vm.$set(this.arr, 3, this.arr[3])
}
}
- 解决方案2
methods: {
change () {
this.arr[3] = 'hangzhou'
// 在全局对象上通知
Vue.set(this.arr, 3, this.arr[3])
}
}
- 解决方案3
methods: {
change () {
// vue本身可以监听到数组的一些方法,例如:
// push(),pop(),shift(),unshift(),splice(),sort(),reverse()
this.arr.splice(3, 1, 'hangzhou')
}
}
版权声明:
作者:Joe.Ye
链接:https://www.appblog.cn/index.php/2023/03/12/vue-data-binding-array-not-updating-view-when-changing-elements-issue/
来源:APP全栈技术分享
文章版权归作者所有,未经允许请勿转载。
共有 0 条评论