更多文章可戳:github.com/MagicalBrid…html
假設有以下代碼:git
<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;
}
}
})
複製代碼
上面的代碼的效果是,當咱們輸入firstName
後,watch
監聽每次修改變化的新值,而後計算出fullName
。github
這裏watch
的一個特色是,最初綁定的時候是不會執行的,要等到firstName
改變的時候才執行監聽計算,那咱們想要一開始就讓他最初綁定的時候就執行怎麼辦呢?咱們須要修改一下咱們的watch
寫法,修改事後的watch
代碼以下:app
watch:{
firstName:{
handler(newName,oldName){
this.fullName = newName+ ' ' + this.lastName
},
// 表明watch裏面聲明瞭firstName這個方法以後當即執行handler方法
immediate: true
},
}
複製代碼
注意到handler了嗎?咱們給firstName
綁定了一個handler方法,以前咱們寫的watch
方法其實默認寫的就是這個handler,Vue.js會處理這個邏輯,最終編譯出來的其實就是這個handler.函數
而immediate:true 表明若是在watch
裏面聲明瞭firstName
以後,就會當即先去執行裏面的handler方法,若是爲false,就和咱們以前的效果同樣,不會再綁定的時候就執行。性能
watch
裏面還有一個屬性deep,默認值是 false 表明的是否深度監聽,好比咱們data裏面有一個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
}
}
})
複製代碼
當咱們在輸入框中輸入數據改變obj.a數據的時候。咱們發現雖然視圖更新了,可是在handler回調並無執行,也就沒有打印obj.a changed
在這裏Vue並不能檢測到對象的屬性的添加或者刪除。因爲Vue在初始化的時候對於屬性執行了getter/setter轉化過程,因此屬性必須在data對象上存在才能讓Vue轉換它,這樣才能讓它是響應式的。ui
默認的狀況下,handle只監聽obj這個屬性它的引用的變化,咱們值有給obj賦值的時候它纔會監聽到,好比咱們在mounted事件鉤子函數中對obj進行從新賦值。這個時候 是能夠觸發 handler 監聽回調的。this
若是咱們想要監聽 obj 裏的屬性a的值呢? 這個時候 deep 屬性就派上用場了!spa
watch: {
obj: {
handler(newName, oldName) {
console.log('obj.a changed');
},
immediate: true,
deep:true
}
}
複製代碼
deep的意思是深刻觀察,監聽器會一層層的往下遍歷,給對象的全部的屬性都添加這個偵聽器,可是 這樣性能開銷就會比較大了,任何修改obj裏面任何一個屬性都會觸發這個偵聽器裏面的handler.
優化,咱們可使用字符串形式進行監聽。
watch:{
'obj.a': {
handler(newName, oldName) {
console.log('obj.a changed');
},
immediate: true
}
}
複製代碼
使用上述的寫法,即便不使用deep屬性選項,依然可以成功的觸發監聽回調。
爲何要註銷watch
? 由於咱們的組件是常常要銷燬的,好比咱們跳轉一個路由,從一個頁面跳轉另外一個頁面。那麼原來的頁面的watch
就沒有用了,這個時候咱們應該註銷原來頁面的watch
否則會有一些性能問題,好在咱們平時都是將watch
寫在組件中的,他會隨着組件的銷燬而銷燬。
const app = new Vue({
template: '<div id="root">{{text}}</div>',
data: {
text: 0
},
watch: {
text(newVal, oldVal){
console.log(`${newVal} : ${oldVal}`);
}
}
});
複製代碼
可是,若是咱們使用下面這樣的方式寫 watch,那麼就要手動註銷了,這種註銷其實也很簡單
const unWatch = app.$watch('text', (newVal, oldVal) => {
console.log(`${newVal} : ${oldVal}`);
})
unWatch(); // 手動註銷watch
複製代碼
app.$watch調用後會返回一個值,就是unWatch
方法,你要註銷 watch
只要調用unWatch
方法就能夠了。
最後謝謝各位小夥伴願意花費寶貴的時間閱讀本文,若是本文給了您一點幫助或者是啓發,請不要吝嗇你的贊和Star,您的確定是我前進的最大動力。github.com/MagicalBrid…