vue.js:当数组更改时,v-for 不会重新渲染内容

Ily*_*rov 3 javascript vue.js

为什么 v-for 对更改数组中的某些元素没有反应?

this.test[3] = 3
Run Code Online (Sandbox Code Playgroud)

如果稍后我将调用 push for array,则只有 Vue 重新渲染内容。

this.test[3] = 3;
this.push(4);
Run Code Online (Sandbox Code Playgroud)

示例:https : //codepen.io/anon/pen/debJqK

this.test[3] = 3
Run Code Online (Sandbox Code Playgroud)
this.test[3] = 3;
this.push(4);
Run Code Online (Sandbox Code Playgroud)
var vm = new Vue({
  el: "#app",

  data: {
    test: [1, 2],
  },
  methods: {
    changeVar1: function() {
      this.test[3] = 3;
      this.test.push(4);
    },
    changeVar2: function() {
      this.test[3] = 3;
    }
  }
})
Run Code Online (Sandbox Code Playgroud)

acd*_*ior 8

如果按索引添加元素,则必须调用Vue.set()

Vue.set(this.test, 3, 3);
Run Code Online (Sandbox Code Playgroud)

或者:

this.test.splice(3, 1, 3)
Run Code Online (Sandbox Code Playgroud)

这使 Vue 能够调整对该元素的反应性。更新了 codePen

为什么?

除了常规的警告问题外,文档还有关于数组的具体指导

注意事项

由于 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' // is NOT reactive
vm.items.length = 2 // is NOT reactive
Run Code Online (Sandbox Code Playgroud)

为了克服警告 1,以下两项都将完成与 相同的操作vm.items[indexOfItem] = newValue,但也会触发反应性系统中的状态更新:

// Vue.set
Vue.set(vm.items, indexOfItem, newValue)

// Array.prototype.splice
vm.items.splice(indexOfItem, 1, newValue)
Run Code Online (Sandbox Code Playgroud)

您还可以使用vm.$set 实例方法,它是 global 的别名Vue.set

vm.$set(vm.items, indexOfItem, newValue)
Run Code Online (Sandbox Code Playgroud)

要处理警告 2,您可以使用splice

vm.items.splice(newLength)
Run Code Online (Sandbox Code Playgroud)

更新的堆栈片段:

Vue.set(this.test, 3, 3);
Run Code Online (Sandbox Code Playgroud)
this.test.splice(3, 1, 3)
Run Code Online (Sandbox Code Playgroud)
var vm = new Vue({
  data: {
    items: ['a', 'b', 'c']
  }
})
vm.items[1] = 'x' // is NOT reactive
vm.items.length = 2 // is NOT reactive
Run Code Online (Sandbox Code Playgroud)