变异方法(mutationmethod),顾名思义,会改变被这些方法调用的原始数组。相比之下,也有非变异(non-mutatingmethod)方法,例如:filter(),concat()和slice()。这些不会改变原始数组,但总是返回一个新数组。当使用非变异方法时,可以用新数组替换旧数组:
example1.items=example1.items.filter(function(item){returnitem.message.match(/Foo/)})
<divid="example">
<div>
<button@click="concat()">concat</button>
<button@click="slice()">slice</button>
<button@click="filter()">filter</button>
</div>
<ul>
<liv-for="iteminitems">
{{item.list}}
</li>
</ul>
</div>
<script>
varexample=newVue({
el:"#example",
data:{
items:[
{list:5},
{list:6},
{list:7}
],
addValue:{list:10}
},
methods:{
concat(){
this.items=this.items.concat(this.addValue)
},
slice(){
this.items=this.items.slice(1)
},
filter(){
this.items=this.items.filter(function(item,index,arr){
return(index>0)
})
}
}
})
以上操作并不会导致Vue丢弃现有DOM并重新渲染整个列表。Vue实现了一些智能启发式方法来最大化DOM元素重用,所以用一个含有相同元素的数组去替换原来的数组是非常高效的操作
注意事项
由于JavaScript的限制,Vue不能检测以下变动的数组:
当你利用索引直接设置一个项时,例如:
vm.items[indexOfItem]=newValue
当你修改数组的长度时,例如:
vm.items.length=newLength
为了解决第一类问题,以下两种方式都可以实现和vm.items[indexOfItem]=newValue相同的效果,同时也将触发状态更新:
//Vue.set
Vue.set(example1.items,indexOfItem,newValue)
//Array.prototype.splice
example1.items.splice(indexOfItem,1,newValue)
为了解决第二类问题,你可以使用splice:
example1.items.splice(newLength)