use Vue.set or vm.$set, or replace the whole array with new one.
As Vue Guide: Reactivity In Depth describes:
Due to the limitations of modern JavaScript (and the abandonment of
Object.observe), Vue cannot detect property addition or deletion.
Since Vue performs the getter/setter conversion process during
instance initialization, a property must be present in the data object
in order for Vue to convert it and make it reactive.
Vue does not allow dynamically adding new root-level reactive
properties to an already created instance. However, it’s possible to
add reactive properties to a nested object using the Vue.set(object,
key, value) method
There are also a few array-related caveats, which already discussed in List Rendering
var vm = new Vue({
el:'#app',
data: {
numbers: [ 1, 2, 3, 4, 5 ]
},
computed: {
evenNumbers: function () {
return this.numbers.filter(function (number) {
return number % 2 === 0
})
}
},
methods: {
changeData1: function () {
this.$set(this.numbers, 0, 6)
},
changeData2: function () {
this.numbers = [ 16, 2, 3, 4, 5 ]
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.js"></script>
<div id="app">
<button @click="changeData1()">Update element with Vue.set or vm.$set</button>
<button @click="changeData2()">replace the whole array</button>
<li v-for="n in evenNumbers">{{ n }}</li>
</div>