昨天提到計算屬性 Computed 是根據相依的資料發生改變,才會重新執行運算,否則就會直接返回暫存的結果,而今天要介紹的監聽器 watch 是根據響應式資料發生改變,而做出一些延伸的應用。
當監聽到資料發生改變時,可以做出其他延伸的應用 (稱作 side effect),例如:修改資料、發送 API 請求資料或觸發 function 執行等。
watch 函數中總共有以下三個參數:
watch(
source,
callback,
{options}
)
以下是官方文件的範例 (Composition API)
當監聽到 question 內容改變時,原本畫面中的 answer 是空值,直到拿到新的值,畫面就會產生變化,也就是說 watch 在資料變化時觸發 side effect,進而修改狀態或取得新的資料,並即時呈現在畫面上。
<script setup>
import { ref, watch } from 'vue'
const question = ref('')
const answer = ref('Questions usually contain a question mark. ;-)')
const loading = ref(false)
// 可以直接偵聽一個 ref
watch(question, async (newQuestion, oldQuestion) => {
if (newQuestion.includes('?')) {
loading.value = true
answer.value = 'Thinking...'
try {
const res = await fetch('https://yesno.wtf/api')
answer.value = (await res.json()).answer
} catch (error) {
answer.value = 'Error! Could not reach the API. ' + error
} finally {
loading.value = false
}
}
})
</script>
<template>
<p>
Ask a yes/no question:
<input v-model="question" :disabled="loading" />
</p>
<p>{{ answer }}</p>
</template>
deep
透過將 watch 的第三個參數寫入 {deep: true},就可以監聽內部深層資料的改變,但深層監聽(Deep Watchers)會遍歷物件所有屬性,因此在資料龐大的狀況下會非常耗能。
immediate
預設是直到監聽對象改變時才會觸發執行函式,透過將 watch 的第三個參數寫入 { immediate: true } 就可以馬上執行。
once
當想要 watch 只執行一次時,可以在 watch 的第三個參數寫入 { once: true } 。
提供更簡潔的監聽方式,無需指定監聽對象,callBack 沒有放參數也可以使用,而且不需要特別加入 immediate 屬性,就會自動追蹤 callBack 函數中使用到的所有響應式資料。
watchEffect(() => { }) // 在大括號內寫入 side effect
以下是官方文件的範例 (Composition API)
const todoId = ref(1)
const data = ref(null)
watch(
todoId,
async () => {
const response = await fetch(
`https://jsonplaceholder.typicode.com/todos/${todoId.value}`
)
data.value = await response.json()
},
{ immediate: true }
)
watchEffect(async () => {
const response = await fetch(
`https://jsonplaceholder.typicode.com/todos/${todoId.value}`
)
data.value = await response.json()
})
watch
immediate: true
)newValue
和 oldValue
參數watchEffect
https://zh-hk.vuejs.org/guide/essentials/watchers.html
https://medium.com/@marsuo52_70945/vue3-watch-watcheffect%E6%80%8E%E9%BA%BC%E7%94%A8-208b2ab2ea0c
https://ithelp.ithome.com.tw/m/articles/10325354
https://ithelp.ithome.com.tw/articles/10308600