Vue.js中 watch(深度監(jiān)聽)

<div>
      <p>FullName: {{fullName}}</p>
      <p>FirstName: <input type="text" v-model="firstName"></p>
</div>

new Vue({
  el: '#root',
  data: {
    firstName: 'Dawei',
    lastName: 'Lou',
    fullName: '' },
  watch: {
    firstName(newName, oldName) { this.fullName = newName + ' ' + this.lastName;
    }
  } 
})</pre>

上面的代碼的效果是,當(dāng)我們輸入firstName后化焕,wacth監(jiān)聽每次修改變化的新值妙同,然后計(jì)算輸出fullName圣勒。

handler方法和immediate屬性

這里 watch 的一個(gè)特點(diǎn)是,最初綁定的時(shí)候是不會(huì)執(zhí)行的攘须,要等到 firstName 改變時(shí)才執(zhí)行監(jiān)聽計(jì)算漆撞。那我們想要一開始就讓他最初綁定的時(shí)候就執(zhí)行改怎么辦呢?我們需要修改一下我們的 watch 寫法于宙,修改過后的 watch 代碼如下:

watch: {
  firstName: {
    handler(newName, oldName) { this.fullName = newName + ' ' + this.lastName;
    }, // 代表在wacth里聲明了firstName這個(gè)方法之后立即先去執(zhí)行handler方法
    immediate: true }
}

注意到handler了嗎浮驳,我們給 firstName 綁定了一個(gè)handler方法,之前我們寫的 watch 方法其實(shí)默認(rèn)寫的就是這個(gè)handler捞魁,Vue.js會(huì)去處理這個(gè)邏輯至会,最終編譯出來其實(shí)就是這個(gè)handler

immediate:true代表如果在 wacth 里聲明了 firstName 之后署驻,就會(huì)立即先去執(zhí)行里面的handler方法奋献,如果為 false就跟我們以前的效果一樣健霹,不會(huì)在綁定的時(shí)候就執(zhí)行。

deep屬性

watch 里面還有一個(gè)屬性 deep瓶蚂,默認(rèn)值是 false糖埋,代表是否深度監(jiān)聽,比如我們 data 里有一個(gè)obj屬性:

<div>
      <p>obj.a: {{obj.a}}</p>
      <p>obj.a: <input type="text" v-model="obj.a"></p>
</div>

new Vue({
  el: '#root',
  data: {
    obj: {
      a: 123 }
  },
  watch: {
    obj: {
      handler(newName, oldName) {
         console.log('obj.a changed');
      },
      immediate: true }
  } 
})

當(dāng)我們?cè)谠谳斎肟蛑休斎霐?shù)據(jù)視圖改變obj.a的值時(shí)窃这,我們發(fā)現(xiàn)是無效的瞳别。受現(xiàn)代 JavaScript 的限制 (以及廢棄 Object.observe)杭攻,Vue 不能檢測(cè)到對(duì)象屬性的添加或刪除兆解。由于 Vue 會(huì)在初始化實(shí)例時(shí)對(duì)屬性執(zhí)行 getter/setter 轉(zhuǎn)化過程锅睛,所以屬性必須在 data 對(duì)象上存在才能讓 Vue 轉(zhuǎn)換它辣垒,這樣才能讓它是響應(yīng)的勋桶。

默認(rèn)情況下 handler 只監(jiān)聽obj這個(gè)屬性它的引用的變化例驹,我們只有給obj賦值的時(shí)候它才會(huì)監(jiān)聽到眠饮,比如我們?cè)?mounted事件鉤子函數(shù)中對(duì)obj進(jìn)行重新賦值:

這樣我們的 handler 才會(huì)執(zhí)行仪召,打印obj.a changed扔茅。

相反召娜,如果我們需要監(jiān)聽obj里的屬性a的值呢秸讹?這時(shí)候deep屬性就派上用場(chǎng)了璃诀!

watch: {
  obj: {
    handler(newName, oldName) {
      console.log('obj.a changed');
    },
    immediate: true,
    deep: true }
} 

deep的意思就是深入觀察劣欢,監(jiān)聽器會(huì)一層層的往下遍歷凿将,給對(duì)象的所有屬性都加上這個(gè)監(jiān)聽器牧抵,但是這樣性能開銷就會(huì)非常大了膳算,任何修改obj里面任何一個(gè)屬性都會(huì)觸發(fā)這個(gè)監(jiān)聽器里的 handler涕蜂。

優(yōu)化蜘拉,我們可以是使用字符串形式監(jiān)聽旭旭。

watch: { 'obj.a': {
    handler(newName, oldName) {
      console.log('obj.a changed');
    },
    immediate: true, // deep: true
 }
} 

這樣Vue.js才會(huì)一層一層解析下去持寄,直到遇到屬性a稍味,然后才給a設(shè)置監(jiān)聽函數(shù)模庐。

注銷watch

為什么要注銷 watch怜姿?因?yàn)槲覀兊慕M件是經(jīng)常要被銷毀的社牲,比如我們跳一個(gè)路由搏恤,從一個(gè)頁面跳到另外一個(gè)頁面,那么原來的頁面的 watch 其實(shí)就沒用了息罗,這時(shí)候我們應(yīng)該注銷掉原來頁面的 watch 的迈喉,不然的話可能會(huì)導(dǎo)致內(nèi)置溢出。好在我們平時(shí) watch 都是寫在組件的選項(xiàng)中的得运,他會(huì)隨著組件的銷毀而銷毀。

const app = new Vue({
  template: '<div id="root">{{text}}</div>',
  data: {
    text: 0 },
  watch: {
    text(newVal, oldVal){
      console.log(`${newVal} : ${oldVal}`);
    }
  }
})

但是,如果我們使用下面這樣的方式寫 watch券坞,那么就要手動(dòng)注銷了,這種注銷其實(shí)也很簡(jiǎn)單

const unWatch = app.$watch('text', (newVal, oldVal) => {
 console.log(`${newVal} : ${oldVal}`);
})

unWatch(); // 手動(dòng)注銷watch

app.$watch調(diào)用后會(huì)返回一個(gè)值,就是unWatch方法布卡,你要注銷 watch 只要調(diào)用unWatch方法就可以了。

2.watch監(jiān)聽路由

我們可以使用watch來進(jìn)行路由的監(jiān)聽

watch: {
    changeShowType(value) {
      console.log("-----"+value);
    }, '$route'(to,from){
      console.log(to); //to表示去往的界面
      console.log(from); //from表示來自于哪個(gè)界面
      if(to.path=="/shop/detail"){
        console.log("商品詳情");
      }
    }
  },
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末薛匪,一起剝皮案震驚了整個(gè)濱河市脓鹃,隨后出現(xiàn)的幾起案子逸尖,更是在濱河造成了極大的恐慌,老刑警劉巖瘸右,帶你破解...
    沈念sama閱讀 218,941評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件娇跟,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡太颤,警方通過查閱死者的電腦和手機(jī)苞俘,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來栋齿,“玉大人苗胀,你說我怎么就攤上這事⊥叨拢” “怎么了?”我有些...
    開封第一講書人閱讀 165,345評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵歌亲,是天一觀的道長(zhǎng)菇用。 經(jīng)常有香客問我,道長(zhǎng)陷揪,這世上最難降的妖魔是什么惋鸥? 我笑而不...
    開封第一講書人閱讀 58,851評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮悍缠,結(jié)果婚禮上卦绣,老公的妹妹穿的比我還像新娘。我一直安慰自己飞蚓,他們只是感情好滤港,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,868評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著趴拧,像睡著了一般溅漾。 火紅的嫁衣襯著肌膚如雪山叮。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,688評(píng)論 1 305
  • 那天添履,我揣著相機(jī)與錄音屁倔,去河邊找鬼。 笑死暮胧,一個(gè)胖子當(dāng)著我的面吹牛锐借,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播往衷,決...
    沈念sama閱讀 40,414評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼瞎饲,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了炼绘?” 一聲冷哼從身側(cè)響起嗅战,我...
    開封第一講書人閱讀 39,319評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎俺亮,沒想到半個(gè)月后驮捍,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,775評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡脚曾,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評(píng)論 3 336
  • 正文 我和宋清朗相戀三年东且,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片本讥。...
    茶點(diǎn)故事閱讀 40,096評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡珊泳,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出拷沸,到底是詐尸還是另有隱情色查,我是刑警寧澤,帶...
    沈念sama閱讀 35,789評(píng)論 5 346
  • 正文 年R本政府宣布撞芍,位于F島的核電站秧了,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏序无。R本人自食惡果不足惜验毡,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,437評(píng)論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望帝嗡。 院中可真熱鬧晶通,春花似錦、人聲如沸哟玷。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,993評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至隘竭,卻和暖如春塘秦,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背动看。 一陣腳步聲響...
    開封第一講書人閱讀 33,107評(píng)論 1 271
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留菱皆,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,308評(píng)論 3 372
  • 正文 我出身青樓京痢,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國和親篷店。 傳聞我的和親對(duì)象是個(gè)殘疾皇子祭椰,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,037評(píng)論 2 355