当数组a的某一项变化时(比如a.splice(0,1,’newVal’)),想获取变化前后的值,直接watch该数组无法获得;而如果直接改变整个数组(比如a=[‘newVal’])没问题
new Vue({
//...
data: {
a: [1,2]
},
methods: {
//点击某按钮后运行
aa: function(){
if(this.a[0] == 1){
this.a.splice(0,1,2)
//this.a = [2,2]
}else{
this.a.splice(0,1,1)
//this.a = [1,2]
}
}
},
watch: {
a: function(newVal, oldVal){
//newVal和oldVal都是改变后的值,即都为newVal
//如果上文aa()中赋值改为this.a=[2,2],可以正常获取这两个参数
console.log(newVal);
console.log(oldVal);
}
}
})
解决方法:设置一个缓冲值
new Vue({
//...
computed: {
//如果直接在下面watch写a时返回的newValue和oldValue会是相同的值
//需要在computed中设置a2进行缓冲
//相当于每次a中内容改变就对a2进行重新赋值,以a2来展示
a2: function() {
return deepClone(this.a); //对a进行深拷贝
}
},
watch: {
a2: function(newValue, oldValue){
//新旧值不同
//alert(JSON.stringify(oldValue))
//alert(JSON.stringify(newValue))
//循环判断不同的值
for (var i = 0; i < newValue.length; i++) {
for (var j = 0; j < newValue[i].length; j++) {
if (oldValue[i][j] != newValue[i][j]) {
//do something
}
}
}
}
}
})
对象也有同样问题,改变其中某个值(比如a.b=1)时获取到的newVal和oldVal相同,也可以使用上面思路解决。
注意对象watch时一般要用深度监听,但这里其实直接改变了整个对象(a={b:111}),而非改变其中某一项,所以普通监听也可以执行。
而数组好像也应该用深度监听的,但用splice后不需要深度监听也可以触发。即使是深度监听a[0]=1这样的赋值也无法触发,因此并没有找到使用深度监听的理由
林秀栋的技术博客