变异方法
Vue 将被侦听的数组的变异方法进行了包裹,这些方法包括:
push()
pop()
shift()
unshift()
splice()
sort()
reverse()
也就是说这些方法也变成了响应式的,当方法执行后,视图也会跟着改变.
替换数组
变异方法,会改变调用了这些方法的原始数组,
相比之下,也有非变异数组,例如:filter()、concat() 和 slice().他们不会改变原数组而是返回一个新数组,当使用非变异方法时,使用新数组替换掉原数组从而达到我们的目的.例如:
example1.items = example1.items.filter(function (item) {
return item.message.match(/Foo/)
})
官方说:
你可能认为这将导致 Vue 丢弃现有 DOM 并重新渲染整个列表。幸运的是,事实并非如此。Vue 为了使得 DOM 元素得到最大范围的重用而实现了一些智能的启发式方法,所以用一个含有相同元素的数组去替换原来的数组是非常高效的操作。
TODO 那么,Vue实现的一些智能的启发式方法指的是哪些方法?
注意事项
由于JavaScript的限制,Vue不能检测以下数组的变动:
1.当你利用索引直接设置一个数组项时,例如:vm.items[indexOfItem] = newValue
这种的就是给数组的其中一项直接重新赋值,那么给整个数组重新定义呢?
<body>
<ul id="app-2" >
<li v-for="item in list">
{{item.name}},{{item.value}}
</li>
<button @click="recover"> 翻转
</ul>
<script>
var vm=new Vue({
el:"#app-2",
data:{
list:[
{name:"zhang",value:"第一个"},
{name:"li",value:"第2个"},
{name:"wang",value:"第3个"}
]
},
methods:{
recover: function(){
alert("进入")
return this.list=[{name:"wang"}];
}
}
});
</script>
</body>
答案是肯定的,因为上述代码中数组list就是data中的属性,是被监听到的,而数组里面的元素则没有被监听到,我们在这里可以看到Vue监听机制的粒度.
第二点:当你修改数组的长度时,例如:vm.items.length = newLength,直接修改长度也不行,因为直接修改长度后,其内容还是没变,数组不会响应式的改变内容,这种写法只是改变了数组的属性length.
那么如何解决这种问题呢?
vue提供了两个方法:
// Vue.set
Vue.set(vm.items, indexOfItem, newValue)
// Array.prototype.splice
vm.items.splice(indexOfItem, 1, newValue)
vm.$set(vm.items, indexOfItem, newValue)
vm.items.splice(newLength)
splice 方法直接接收一个参数的话其实相当于去除掉这个长度之后的所有数据