vue.js:v-for在数组更改时没有重新呈现内容

时间:2018-04-17 14:42:31

标签: javascript vue.js

为什么v-for不会改变数组中的某些元素?

this.test[3] = 3

如果稍后我会调用push for array,只有Vue重新呈现内容。

this.test[3] = 3;
this.push(4);

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



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;
    }
  }
})

html * {
  box-sizing: border-box;
}

body {
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  padding: 4em;
}

<script src="https://cdn.jsdelivr.net/vue/1.0.26/vue.min.js"></script>

<div id="app">
  <button @click="changeVar1()">Work</button>
  <button @click="changeVar2()">Doesn't work</button>
  <p v-for="(index, digit) in test">{{digit}}</p>
</div>
&#13;
&#13;
&#13;

1 个答案:

答案 0 :(得分:1)

如果按索引添加元素,则为have to call Vue.set()

Vue.set(this.test, 3, 3);

或者:

this.test.splice(3, 1, 3)

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

为什么?

除了常见的警告问题外,文档还有a specific guidance on arrays

  

注意事项

     

由于JavaScript的限制,Vue 无法检测到以下内容   更改为数组:

     
      
  1. 直接设置带索引的项目时,例如vm.items[indexOfItem] = newValue
  2.   
  3. 修改数组的长度时,例如: vm.items.length = newLength
  4.         

    例如:

    var vm = new Vue({
      data: {
        items: ['a', 'b', 'c']
      }
    })
    vm.items[1] = 'x' // is NOT reactive
    vm.items.length = 2 // is NOT reactive
    
         

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

    // Vue.set
    Vue.set(vm.items, indexOfItem, newValue)
    
    // Array.prototype.splice
    vm.items.splice(indexOfItem, 1, newValue)
    
         

    您还可以使用vm.$set   实例方法,它是全局Vue.set

    的别名
    vm.$set(vm.items, indexOfItem, newValue)
    
         

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

    vm.items.splice(newLength)
    

更新了堆栈代码段:

var vm = new Vue({
  el: "#app",

  data: {
    test: [1, 2],
  },
  methods: {
    changeVar1: function() {
      this.test[3] = 3;
      this.test.push(4);
    },
    changeVar2: function() {
      Vue.set(this.test, 3, 3);
      // this.test.splice(3, 1, 3); // would work the same
    }
  }
})
html * {
  box-sizing: border-box;
}

body {
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  padding: 4em;
}
<script src="https://cdn.jsdelivr.net/vue/1.0.26/vue.min.js"></script>

<div id="app">
  <button @click="changeVar1()">Work</button>
  <button @click="changeVar2()">Didn't work, now fixed</button>
  <p v-for="(index, digit) in test">{{digit}}</p>
</div>