什么是watch
當我們需要根據一個數據的變化來進行一些操作的時候我們需要使用偵聽器,它能夠在響應式數據發生變化的時候觸發提供的回調函數
基礎偵聽
watch 可以偵聽不同的數據源。例如:
- ref
- 計算屬性
- 響應式對象
- getter函數
- 多個數據源組層的數據
const x = ref(0)
const y = ref(0)// 單個 ref
watch(x, (newX) => {console.log(`x is ${newX}`)
})// getter 函數
watch(() => x.value + y.value,(sum) => {console.log(`sum of x + y is: ${sum}`)}
)// 多個來源組成的數組
watch([x, () => y.value], ([newX, newY]) => {console.log(`x is ${newX} and y is ${newY}`)
})
不能直接偵聽響應式對象的屬性,應使用如下代碼
// 提供一個 getter 函數
watch(() => obj.count,(count) => {console.log(`count is: ${count}`)}
)
深層偵聽器
如果直接傳入響應式對象,會默認創建深層監聽,該回調函數會在所有嵌套的數據是觸發。
如果我們想只監聽對象中的某個屬性發生變化在觸發則使用如下代碼.
watch(() => state.someObject,() => {// 僅當 state.someObject 變化時觸發}
)
如果我們想要顯式的聲明可以使用watch
的第三個參數{deep:treue}
來轉換為強制偵聽。
立即執行
有時候我們需要一進入頁面就執行偵聽器一次,那我們可以使用watch的第三個參數
{immediate:treue}`來立即執行。
watchEffect的使用
- watchEffect 是立即執行一次的,不需要指定
immediate
。 - watch 只會追中明確偵聽的數據源,而watchEffect 會自動追中所有能訪問到的響應式數據。
watchEffect(async () => {const response = await fetch(`https://jsonplaceholder.typicode.com/todos/${todoId.value}`)data.value = await response.json()
})
TIP
watchEffect 僅會在其同步執行期間,才追蹤依賴。在使用異步回調時,只有在第一個 await 正常工作前訪問到的屬性才會被追蹤。
回調觸發時機
默認情況下,偵聽器回調會在父組件更新 (如有) 之后、所屬組件的 DOM 更新之前被調用。這意味著如果你嘗試在偵聽器回調中訪問所屬組件的 DOM,那么 DOM 將處于更新前的狀態。
如果想在偵聽器回調中能訪問被 Vue 更新之后的所屬組件的 DOM,你需要指明 flush: ‘post’ 選項:
watch(source, callback, {flush: 'post'
})watchEffect(callback, {flush: 'post'
})
后置刷新的 watchEffect() 也可以使用 watchPostEffect()