Vue+watch如何實(shí)現(xiàn)深度監(jiān)聽(tīng)

一、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è)");
      }
    }
  },
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容