今天在重構項目的時候,發現了一個有關父子組件之間實時通訊的問題。在上個版本中,代碼如下:
props: {
// 接收父組件傳遞過來的信息
chartData: {
type: Object,
default: ()=>[]
}
},
data () {
return {
}
},
watch: {
'chartData.data': function (n, o) {
this.$nextTick (() => {
console.log(n, o)
})
}
}
之前執行起來一點問題都沒有(我也郁悶為什么。。。)。但是今天,明明是一樣的代碼,完全監聽不到啊!
開始查文檔,普通的watch方法無法監聽到對象內部屬性的改變,只有data中的數據才能夠監聽到變化,我傳的就是Object,所以無法獲取到對象內部的改變。
OK。開始筆記吧。
watch的用法大概有三種。
1、基本用法:(注意:只能watch基礎類型的變量)
<div>
<p>fname: <input type="text" v-model="fname"></p>
<p>name: {{name}}</p>
</div>
new Vue({
el: '#root',
data: {
fname: '肖戰',
name: ''
},
watch: {
fname (n, o) {
console.log(n, o)
}
}
})
2、handler方法和immediate屬性
這種方法的特點是,當值第一次綁定的時候不會執行監聽函數,只有值發生改變才會執行。如果我們需要在最開始綁定值的時候也執行函數,就需要用到immediate屬性。
比如當父組件向子組件動態傳值時,子組件props首次獲取到父組件傳來的默認值時,也需要執行函數,此刻就需要將immediate設置為true。
props: {
chartData: {
type: Object,
default: () => []
}
},
watch: {
// 對象監聽
chartData: {
handler (newValue, oldValue) {
console.log(newValue, oldValue)
},
immediate: true
}
},
監聽的數據后面寫成對象形式。之前我們寫的函數其實就是再寫handler這個方法;
immediate表示在watch中首次綁定的時候,是否執行handler,值為true表示在watch中聲明的時候,立即執行。值為false就和一般使用watch一樣,在數據發生變化的時候才執行。
3、deep屬性(深度監聽,常用語對象下面屬性的改變)
當需要監聽一個對象的改變時,普通的watch方法無法監聽到對象內部屬性的改變,只有data中的數據才能夠監聽到變化,此時就需要deep屬性對對象進行深度監聽。
<input type="text" v-model="chartData.data"/>
data () {
return {
chartData: {
data: '肖戰'
}
}
},
watch: {
// 對象監聽
chartData: {
handler (newValue, oldValue) {
console.log(newValue, oldValue)
},
deep: true
}
},
設置deep:true,可以監聽到chartData.data的變化,此時會給chartData的所有屬性都加上這個監聽器,當對象屬性較多時,每個屬性值的變化都會執行handler。如果只需要監聽對象中的一個屬性值,可以做個優化:使用字符串的形式來監聽對象屬性:
watch: {
// 對象監聽
'chartData.data': {
handler (newValue, oldValue) {
console.log(newValue, oldValue)
},
deep: true
}
},
這樣只會給對象的某個特定的屬性加監聽器。
數組(一維、多維)的變化不需要通過深度監聽,對象數組中對象的屬性變化則需要deep深度監聽。
如果你有更好的方法,可以給我點意見哦。