Watch
watch是一个对象,这个对象的键是需要观察的表达式,值可以是饥饿值方法、方法名、包含选项的对象等的,Vue实例会在实例化的时候调用$watch(),遍历watch对象的每一个属性高,并且观察。
可以侦听1个或多个响应数据源数据,并在数据源发生变化啊时调用所给的回调函数。
注意,本文不会阐述watch对象的具体实现源码,只是介绍watch对象键值的五种使用方式。
使用方式
- 最直接的,直接用方法作为回调函数(或者说作为值)
<div>
<p>{{msg}}</p>
<input v-model="msg">
</div>
// pattern1 directly method value
watch {
// msg1 为表达式, function(oldVal, newVal)为匿名函数,作为回调函数
msg1: function (newVal, oldVal) {
console.log("oldVal is: " + oldVal + " newVal is: " + newVal);
}
}
回调函数的第一个参数是新值,第二个是旧值。
- 函数名作为值
// pattern 2 use function name as value
watch {
msg2: "methodway"
}
methods: {
methodway (newVal, oldVal) {
console.log("oldVal is: " + oldVal + " newVal is: " + newVal);
}
}
- 观察键为对象/数组时,需要追加选项deep
被观察者是一个对象/数组的时候,改变对象内部属性的值,用通常watch方式是捕捉不到的。因为对于数组、对象本身来说,它并没有改变,需要加上选项deep:true。
watch {
msg3: {
handler: function (newVal, oldVal) {
console.log("oldVal is: " + oldVal + " newVal is: " + newVal);
},
// 加上这个选项之后,不论被嵌套得多深,被观察的对象的property一旦改变都会响应
deep:true
}
}
虽然捕捉到比安欢,但是从watch对象里面的回调来说,无法准确抓取到变化的属性。如果想做到这点,可以单独观察对象某个属性。如果想做到这点,可以单独观察对象的某个属性msg3.attr1或者使用computed做中间层来观察。
// computed做中间层,注意,并不是非要这样多写一层进行观察,可以直接观察属性
computed: {
msg3attr() {
return this.msg3.attr1;
}
}
watch {
msg3attr:
function(newVal, oldVal) {
console.log("oldVal is: " + oldVal + " newVal is: " + newVal);
}
}
- 实例化后立刻回调
要求Vue对象实例化后,立刻回调某一个Watch对象的键值。加上选项immediate:true即可。
<div>
<p>{{msg4}}</p>
<input v-model="msg4">
</div>
watch {
msg4: {
handler(newVal, oldVal) {
console.log("this should be called immediately.");
},
// 加上immediate选项后,实例化后立刻回调一次
immediate:true
},
}
- 回调函数数组
有多个回调函数需要执行,可以将Watch的值赋值为一个数组,数组的函数将被逐一调用。
<div>
<p>{{msg5}}</p>
<input v-model="msg5">
</div>
watch {
msg5: [
"methodchain1",
function methodchain2(oldVal,newVal) {
console.log("second method");
},
{
handler(newVal, oldVal) {
console.log("third method")
},deep:true
}
]
},
methods: {
methodchain1(newVal, oldVal) {
console.log("first method");
}
}
值得一提的是,watch对象中,有时候可以省略,用键的名字直接用作为回调函数的名称,同样能正常观察到表达式的变化。
Watch对象中的回调函数不应该用箭头函数进行定义,它将导致上下文的混乱,this将指向错误的上下文。