在 Vue 3 里,watch
和 watchEffect
都是用于響應式數據變化的 API,但它們在使用方法和應用場景上存在差異。下面詳細介紹它們的用法和區別。
用法
watch
watch
用于監聽特定的響應式數據源,當數據源發生變化時,會執行相應的回調函數。它可以監聽單個數據源,也能監聽多個數據源。
監聽單個數據源:
import { ref, watch } from 'vue';const count = ref(0);watch(count, (newValue, oldValue) => {console.log(`count 從 ${oldValue} 變為 ${newValue}`);
});count.value = 1;
在這個例子中,watch
監聽 count
的變化,當 count
的值改變時,回調函數會被觸發,打印出新舊值。
監聽多個數據源:
import { ref, watch } from 'vue';const count1 = ref(0);
const count2 = ref(0);watch([count1, count2], ([newCount1, newCount2], [oldCount1, oldCount2]) => {console.log(`count1 從 ${oldCount1} 變為 ${newCount1},count2 從 ${oldCount2} 變為 ${newCount2}`);
});count1.value = 1;
這里 watch
監聽 count1
和 count2
的變化,當其中任何一個值改變時,回調函數就會被觸發。
watchEffect
watchEffect
會立即執行傳入的函數,并自動追蹤函數內部依賴的所有響應式數據。當這些依賴的數據發生變化時,函數會再次執行。
import { ref, watchEffect } from 'vue';let props = defineProps(['orderid','randomid'])
const count = ref(0);watchEffect(() => {//此函數內監聽的任何值有變化都會觸發此函數的執行,要想每次都執行可以外部引入隨機數console.log('watchEffect',props.orderid,props.randomid) //通過引入生成的隨機數randomid,即使orderid沒有變化,此函數也會執行一遍,實現實時刷新console.log(`count 的值是 ${count.value}`);});count.value = 1;
在這個例子中,watchEffect
會立即執行回調函數,打印出 count
的初始值。當 count
的值改變時,回調函數會再次執行,打印出新的值。通過引入生成的隨機數randomid,即使orderid,count 沒有變化,此函數也會執行一遍,實現實時刷新
區別
1. 觸發時機
watch
:默認情況下,只有當監聽的數據源發生變化時,回調函數才會執行。它不會在組件初始化時立即執行回調函數,除非設置了immediate: true
選項。watchEffect
:會立即執行傳入的函數,并且在依賴的響應式數據發生變化時再次執行。
2. 依賴追蹤
watch
:需要明確指定要監聽的數據源,它只會監聽這些明確指定的數據源的變化。watchEffect
:會自動追蹤函數內部依賴的所有響應式數據,無需手動指定。這使得代碼更加簡潔,但也可能導致意外的重新執行,因為任何被函數訪問的響應式數據的變化都會觸發函數的重新執行。
3. 舊值獲取
watch
:回調函數可以接收兩個參數,分別是新值和舊值,方便對比數據的變化。watchEffect
:無法直接獲取舊值,因為它沒有明確的新舊值對比機制。
4. 應用場景
watch
:適用于需要在數據變化時執行特定操作,并且需要對比新舊值的場景,比如在數據變化時發送網絡請求、更新其他數據等。watchEffect
:適用于需要在響應式數據變化時自動更新副作用的場景,比如在數據變化時更新 DOM、計算派生數據等,不需要明確指定依賴的情況。