一、handler方法和immediate屬性
watch 的一個(gè)特點(diǎn)是,最初綁定的時(shí)候是不會(huì)執(zhí)行的,要等到 所監(jiān)聽(tīng)的值發(fā)生改變時(shí)才執(zhí)行監(jiān)聽(tīng)計(jì)算。
那我們想要一開(kāi)始就讓他最初綁定的時(shí)候就執(zhí)行該怎么辦呢?
watch 代碼如下:
watch: {
combineVal: {
handler(newVal, oldVal) {
this.combineVal = newVal + '-' + this.oldVal;
},
// 代表在wacth里聲明了combineVal這個(gè)方法之后立即先去執(zhí)行handler方法
immediate: true
}
}
當(dāng)我們給 combineVal 綁定了一個(gè)handler方法,Vue.js會(huì)去處理這個(gè)邏輯,最終編譯出來(lái)其實(shí)就是這個(gè)handler。
而immediate:true代表如果在 wacth 里聲明了 newVal 之后,就會(huì)立即先去執(zhí)行里面的handler方法,如果為 false就不會(huì)在綁定的時(shí)候就執(zhí)行。
二、deep屬性
watch 里面還有一個(gè)屬性 deep,默認(rèn)值是 false,代表是否深度監(jiān)聽(tīng),比如我們 data 里有一個(gè)obj屬性:
默認(rèn)情況下 handler 只監(jiān)聽(tīng)obj這個(gè)屬性它的引用的變化,我們只有給obj賦值的時(shí)候它才會(huì)監(jiān)聽(tīng)到。
如果我們需要監(jiān)聽(tīng)obj里的屬性a的值呢?這時(shí)候deep屬性就派上用場(chǎng)了!
watch: {
obj: {
handler(newVal, oldVal) {
console.log('obj.a changed');
},
immediate: true,
deep: true
}
}
1.問(wèn)題
deep的意思就是深入觀察,監(jiān)聽(tīng)器會(huì)一層層的往下遍歷,給對(duì)象的所有屬性都加上這個(gè)監(jiān)聽(tīng)器,但是這樣性能開(kāi)銷(xiāo)就會(huì)非常大了,任何修改obj里面任何一個(gè)屬性都會(huì)觸發(fā)這個(gè)監(jiān)聽(tīng)器里的 handler。
2.優(yōu)化
watch: {
'obj.a': {
handler(newVal, oldVal) {
console.log('obj.a changed');
},
immediate: true,
deep: true
}
}
這樣Vue.js才會(huì)一層一層解析下去,直到遇到屬性a,然后才給a設(shè)置監(jiān)聽(tīng)函數(shù)。
三、注銷(xiāo)watch
為什么要注銷(xiāo) watch?
因?yàn)槲覀兊慕M件是經(jīng)常要被銷(xiāo)毀的,比如我們跳一個(gè)路由,從一個(gè)頁(yè)面跳到另外一個(gè)頁(yè)面,那么原來(lái)的頁(yè)面的 watch 其實(shí)就沒(méi)用了,這時(shí)候我們應(yīng)該注銷(xiāo)掉原來(lái)頁(yè)面的 watch 的,不然的話(huà)可能會(huì)導(dǎo)致內(nèi)置溢出。
好在我們平時(shí) watch 都是寫(xiě)在組件的選項(xiàng)中的,他會(huì)隨著組件的銷(xiāo)毀而銷(xiāo)毀。
1.手動(dòng)注銷(xiāo)
如果我們使用下面這樣的方式寫(xiě) watch,那么就要手動(dòng)注銷(xiāo)了
const unWatch = app.$watch('text', (newVal, oldVal) => {
console.log(`${newVal} : ${oldVal}`);
})
unWatch(); // 手動(dòng)注銷(xiāo)watch
app.$watch調(diào)用后會(huì)返回一個(gè)值,就是unWatch方法,你要注銷(xiāo) watch 只要調(diào)用unWatch方法就可以了。
2.watch監(jiān)聽(tīng)路由
watch: {
changeShowMenu(value) {
console.log("-----"+value);
},
'$route'(to,from){
console.log(to); //to表示去往的界面
console.log(from); //from表示來(lái)自于哪個(gè)界面
if(to.path=="/home"){
console.log("主頁(yè)");
}
}
},