之前也都沒使用過 watch
,所以趁這個機會好好了解一下它。
const vm = new Vue({
el:'#app',
data:{
msg:''
},
watch:{
//被偵聽的資料名稱(新值,舊值){}
msg(newMsg,oldMsg){
console.log('newMsg',newMsg)
console.log('oldMsg',oldMsg)
}
}
})
watch
裡的 msg
代表的就是我們所偵聽的資料( data
裡 msg
),當偵聽的資料值發生變化時,就會去執行 watch
裡的 msg()
,而 msg(newMsg,oldMsg)
裡的參數一定是先新後舊。
handler
方法及屬性 immediate
、 deep
handler
方法及 immediate
屬性const vm = new Vue({
el:'#app',
data:{
msg:'',
msg2:'',
user:{
firstName: 'John',
lastName:'Smith',
age:0
},
user2:{
firstName: 'Mary',
lastName:'Wonder',
age:0
}
},
watch:{
msg(newMsg,oldMsg){
console.log('newMsg',newMsg)
console.log('oldMsg',oldMsg)
this.user.age = 30
},
msg2: {
handler(newMsg2,oldMsg2){
this.user2.age = 20
},
immediate:true
}
}
})
比較 watch
裡 msg
跟 msg2
的差別,會發現 user.age
的值會是原始值0,但是 user2.age
的值卻是執行 watch
裡 msg2
後的結果,雖然 Vue 在實例化的過程中會先遍歷過所有 watch
裡所有物件的屬性,但卻不會去執行這些物件,而是等到他們所監聽的資料有所改變的時候,才會去執行裡面的方法,除非是加入了 immediate
這個屬性。immediate
屬性的作用就是在最初綁定這個物件( msg2
)的時候( created()
前),就去執行這個物件的方法( handler()
),所以在畫面一開始 user2.age
就會呈現經過 watch
裡 msg2
作用後的結果值20。
使用 deep
屬性
const vm = new Vue({
el:'#app',
data:{
cellPhone:{
type:'apple',
years:2
}
},
watch:{
cellPhone: {
handler(newcellPhone,oldcellPhone){
console.log(this.cellPhone)
},
immediate:true,
// deep:true
}
},
created(){
this.cellPhone = {
msg:'重新賦值可以被偵聽到',
type:'Samsung',
years:10
}
}
})
當修改 cellPhone.type
值時, watch
裡的 cellPhone{handler...}
並不會執行,這是因為 Vue 沒辦法偵聽到物件裡的屬性變化,而只能偵聽到物件的變化,像是重新賦值之類的。
如果要偵聽到物件裡的屬性變化,就必須加入 deep
屬性,這樣當 cellPhone
物件裡不管哪個屬性改變時,都會觸發 watch
裡的 cellPhone{handler...}
。
使用字串作為偵聽對象
const vm = new Vue({
el:'#app',
data:{
cellPhone:{
type:'apple',
years:2
},
cellPhone2:{
type:'oppo',
years:1
}
},
watch:{
'cellPhone2.type': {
handler(newcellPhone,oldcellPhone){
console.log(this.cellPhone2)
},
immediate:true
}
}
})
偵聽的對象就是物件裡的屬性,只有指定的這個屬性有改變時才會觸發 watch
裡偵聽的對象裡的方法。
比較上述2種寫法的差別:
deep
屬性):能夠偵聽到 cellPhone
裡所有的屬性,只要其中一個(如 type
、years
)有改變,那麼就會執行 watch
裡的 cellPhone{handler...}
。cellPhone2.type
,只有 cellPhone2.type
有改變,才會去執行 watch
裡的 cellPhone2{handler...}
。
immediate
或是deep
屬性默認值都是false
,如果要加入immediate
或是deep
屬性,那麼寫法就需變成物件形式,如msg2: {handler(){...},immediate:true,deep:true}
,handler
就是在資料改變時要執行的方法,而immediate
屬性指的是在最初綁定時就要去執行handler
方法,deep
屬性指的是能夠讀取資料裡更深層的資料(像是cellPhone
裡的type
、years
)。
watch
跟 computed
使用時機computed
的 getter
方法只能接收它所依賴的響應式資料的改變,之後返回一個值,而 setter
方法是在本身值改變時,才能執行一些事情,但是本身的值還是 getter
方法所得到值。Demo:[DAY04]跟 Vue.js 認識的30天 - Vue 的資料偵聽(watch)
參考資料:
Vue.js-watch
龙恩0707-vue系列---理解Vue中的computed,watch,methods的区别及源码实现(六)
感謝分享
補充 new Vue() 是 Vue 2 的語法,
Vue 3 用 Vue.createApp() 取代 new Vue()
https://book.vue.tw/appendix/migration.html#%E5%85%83%E4%BB%B6%E5%AF%A6%E9%AB%94%E5%BB%BA%E7%AB%8B
Vue 2 support will end on Dec 31, 2023. Learn more about Vue 2 Extended LTS.
The Benefits of the New Vue 3 App Initialization Code