假設有如下代碼:
···
FullName: {{fullName}}
FirstName:
new Vue({ el: '#root', data: { firstName: 'Dawei', lastName: 'Lou', fullName: '' }, watch: { firstName(newName, oldName) { this.fullName = newName + ' ' + this.lastName; } } })
···
複制代碼
上面的代碼的效果是,當我們輸入firstName後,wacth監聽每次修改變化的新值,然後計算輸出fullName。
handler方法和immediate屬性
這裡 watch 的一個特點是,最初綁定的時候是不會執行的,要等到 firstName 改變時才執行監聽計算。那我們想要一開始就讓他最初綁定的時候就執行改怎麼辦呢?我們需要修改一下我們的 watch 寫法,修改過後的 watch 代碼如下:
···
watch: { firstName: { handler(newName, oldName) { this.fullName =
newName + ’ ’ + this.lastName; }, //
代表在wacth裡聲明了firstName這個方法之後立即先去執行handler方法 immediate: true } }
···
複制代碼
注意到handler了嗎,我們給 firstName 綁定了一個handler方法,之前我們寫的 watch 方法其實預設寫的就是這個handler,Vue.js會去處理這個邏輯,最終編譯出來其實就是這個handler。
而immediate:true代表如果在 wacth 裡聲明了 firstName 之後,就會立即先去執行裡面的handler方法,如果為 false就跟我們以前的效果一樣,不會在綁定的時候就執行。
deep屬性
watch 裡面還有一個屬性 deep,預設值是 false,代表是否深度監聽,比如我們 data 裡有一個obj屬性:
···
obj.a: {{obj.a}}
obj.a:
new Vue({ el: '#root', data: { obj: { a: 123 } }, watch: { obj: { handler(newName, oldName) { console.log('obj.a changed'); }, immediate: true } } }) 複制代碼
···
當我們在在輸入框中輸入資料視圖改變obj.a的值時,我們發現是無效的。受現代 JavaScript 的限制 (以及廢棄 Object.observe),Vue 不能檢測到對象屬性的添加或删除。由于 Vue 會在初始化執行個體時對屬性執行 getter/setter 轉化過程,是以屬性必須在 data 對象上存在才能讓 Vue 轉換它,這樣才能讓它是響應的。
預設情況下 handler 隻監聽obj這個屬性它的引用的變化,我們隻有給obj指派的時候它才會監聽到,比如我們在 mounted事件鈎子函數中對obj進行重新指派:
···
mounted: { this.obj = { a: ‘456’ } } 複制代碼
···
這樣我們的 handler 才會執行,列印obj.a changed。
相反,如果我們需要監聽obj裡的屬性a的值呢?這時候deep屬性就派上用場了!
···
watch: { obj: { handler(newName, oldName) { console.log(‘obj.a
changed’); }, immediate: true, deep: true } } 複制代碼
··
優化,我們可以是使用字元串形式監聽。
···
watch: { ‘obj.a’: { handler(newName, oldName) { console.log(‘obj.a
changed’); }, immediate: true, // deep: true } } 複制代碼
這樣Vue.js才會一層一層解析下去,直到遇到屬性a,然後才給a設定監聽函數。
登出watch
為什麼要登出 watch?因為我們的元件是經常要被銷毀的,比如我們跳一個路由,從一個頁面跳到另外一個頁面,那麼原來的頁面的 watch 其實就沒用了,這時候我們應該登出掉原來頁面的 watch 的,不然的話可能會導緻内置溢出。好在我們平時 watch 都是寫在元件的選項中的,他會随着元件的銷毀而銷毀。
···
const app = new Vue({ template: ‘
{{text}} ’,
data: { text: 0 }, watch: { text(newVal, oldVal){
console.log(
); } } }); 複制代碼
${newVal} : ${oldVal}
但是,如果我們使用下面這樣的方式寫 watch,那麼就要手動登出了,這種登出其實也很簡單
const unWatch = app.KaTeX parse error: Expected '}', got 'EOF' at end of input: … console.log(`{newVal} : ${oldVal}`); }) unWatch(); // 手動登出watch 複制代碼
app.$watch調用後會傳回一個值,就是unWatch方法,你要登出 watch 隻要調用unWatch方法就可以了。
分享移動開發與微信小程式開發該做哪些!其中有哪些關鍵的技術點!需要下圖學習教程的歡迎加入web前端交流群:854591759擷取!
點選連結加入群聊【web前端交流群】: