Vue数据绑定数组,改变元素时不更新view问题

问题描述

关于这个问题,Vue官方文档上说的很清楚

由于 JavaScript 的限制,Vue 不能检测以下变动的数组:

  1. 当你利用索引直接设置一个项时,例如:vm.items[indexOfItem] = newValue
  2. 当你修改数组的长度时,例如: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全栈技术分享
文章版权归作者所有,未经允许请勿转载。

THE END
分享
二维码
打赏
海报
Vue数据绑定数组,改变元素时不更新view问题
问题描述 关于这个问题,Vue官方文档上说的很清楚 由于 JavaScript 的限制,Vue 不能检测以下变动的数组: 当你利用索引直接设置一个项时,例如:vm.items[in……
<<上一篇
下一篇>>
文章目录
关闭
目 录