VUE3 中的 Watch 詳解

一、監聽基礎類型

const nums = ref(9)

watch(nums, (newValue, oldValue) => {
    console.log('watch 已觸發', newValue)
})

 

二、監聽複雜類型

const demo = reactive({
	name: '前端小玖',
	nickName: '小玖',
	soulmate: {
		name: '',
		nickName: ''
	}
})

 

複雜類型的監聽有很多種情況,具體的內容如下

 

  1. 監聽整個對象
watch(demo, (newValue, oldValue) => {
    console.log('watch 已觸發', newValue)
})

其第一個參數是直接傳入要監聽的對象。當監聽整個對象時,只要這個對象有任何修改,那麼就會觸發 watch 方法。無論是其子屬性變更(如 demo.name),還是孫屬性變更(如 demo.soulmate.name)...,都是會觸發 watch 方法的。

 

2. 監聽對象中的某個屬性

// 監聽demo對象的name屬性

watch(() => demo.name, (newValue, oldValue) => {
    console.log('watch 已觸發', newValue)
})

如上代碼,監聽 demo 對象的 name 屬性,那麼只有當 demo 對象的 name 屬性發生變更時,纔會觸發 watch 方法,其他屬性變更不會觸發 watch 方法。注意,此時的第一個參數是一個箭頭函數

 

3. 只監聽對象的子屬性

watch(() => ({ ...demo }), (newValue, oldValue) => {
    console.log('watch 已觸發', newValue)
})

這種情況,只有當 demo 的子屬性發生變更時纔會觸發 watch 方法。孫屬性,曾孫屬性... 發生變更都不會觸發 watch 方法。也就是說,當你修改 demo.soulmate.name 或者 demo.soulmate.nickName 時是不會觸發 watch 方法的。

 

4. 監聽對象的所有屬性

watch(() => demo, (newValue, oldValue) => {
	console.log('watch 已觸發', newValue)
}, { deep: true })

這個相當於監聽整個對象(效果與上面的第一種相同)。但是實現方式與上面第一種是不一樣的,這裏我們可以看到,第一個參數是箭頭函數,並且還多了第三個參數 { deep: true }。當加上了第三個參數 { deep: true },那麼就不僅僅是監聽對象的子屬性了,它還會監聽 孫屬性,曾孫屬性 ...

通常要實現監聽對象的所有屬性,我們都會採用上面第一種方法,原因無他,第一種編碼簡單,第一個參數直接傳入 demo 即可。

 

三、組合監聽

const nums = ref(9)
const demo = reactive({
	name: '前端小玖',
	nickName: '小玖',
	soulmate: {
		name: '',
		nickName: ''
	}
})

什麼是組合監聽呢?舉個例子,比如我想同時監聽 demo 對象的 name 屬性,和基礎類型 nums,只要他們其中任何一個發生變更,那麼就觸發 watch 方法。

watch([() => demo.name, nums], ([newName, newNums], [oldName, oldNums]) => {
	console.log('watch 已觸發: name', newName)
	console.log('watch 已觸發: nums', newNums)
})

注意,此時的第一個參數是一個數組,且第二參數箭頭函數的參數也是數組的形式。

 

四、其他

與 VUE2 中的 watch 不同,VUE3 可以多次使用 watch 方法,通過多個watch 方法來監聽多個對象。而 VUE2 則是把所有的要監控的對象放在 watch 裏面。

VUE2 代碼:

watch: {
    nums () {},
    'demo.name' () {}
}

 

VUE3 代碼:

watch(nums, () => {})
watch(() => demo.name, () => {})

 

關於 watch 的第三個參數,除了布爾類型的 deep,還有一個布爾類型的 immediate。源碼中的接口聲明如下:

export declare interface WatchOptions<Immediate = boolean> extends WatchOptionsBase
{
    immediate?: Immediate;
    deep?: boolean;
}

immediate 的作用就是設置是否立即執行監控,當我們將其值設置爲 true 時,那麼被監控的對象在初始化時就會觸發一次 watch 方法,相當於頁面一刷新就會觸發。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章