Vue偵聽器:watch與watchEffect的區(qū)別與使用
watch與watchEffect的核心區(qū)別
watch 和 watchEffect 都是 Vue 中用于偵聽響應(yīng)式數(shù)據(jù)變化的工具,但它們的依賴追蹤方式、執(zhí)行時機和使用場景有顯著區(qū)別。
| 特性 | watch | watchEffect |
|---|---|---|
| 依賴追蹤方式 | 顯式指定偵聽的數(shù)據(jù)源(如 ref、reactive 屬性) | 隱式追蹤回調(diào)函數(shù)內(nèi)部的響應(yīng)式依賴 |
| 執(zhí)行時機 | 默認懶執(zhí)行(首次不執(zhí)行,僅在數(shù)據(jù)源變化時執(zhí)行) | 立即執(zhí)行(組件掛載時立即執(zhí)行一次) |
| 回調(diào)參數(shù) | 提供新值和舊值(如 (newVal, oldVal) => {}) | 無參數(shù)(通過函數(shù)內(nèi)部的依賴自動觸發(fā)) |
| 適用場景 | 需要知道數(shù)據(jù)變化前后的值,或偵聽特定數(shù)據(jù)源 | 需要根據(jù)多個依賴執(zhí)行副作用(如數(shù)據(jù)請求) |
| 停止偵聽 | 返回一個停止函數(shù)(如 const stop = watch(...)) | 返回一個停止函數(shù)(如 const stop = watchEffect(...)) |
使用
watch使用
watch 用于顯式偵聽一個或多個響應(yīng)式數(shù)據(jù)源,當數(shù)據(jù)源變化時執(zhí)行回調(diào)函數(shù)。
- 偵聽單個 ref
import { ref, watch } from 'vue';
const count = ref(0);
// 偵聽 count 的變化
watch(count, (newVal, oldVal) => {
console.log(`count 從 ${oldVal} 變?yōu)?${newVal}`);
});
// 修改 count,觸發(fā) watch 回調(diào)
count.value = 1; // 輸出:count 從 0 變?yōu)?1
- 偵聽多個 ref
import { ref, watch } from 'vue';
const a = ref(0);
const b = ref(0);
// 偵聽多個數(shù)據(jù)源
watch([a, b], ([newA, newB], [oldA, oldB]) => {
console.log(`a 從 ${oldA} 變?yōu)?${newA}`);
console.log(`b 從 ${oldB} 變?yōu)?${newB}`);
});
// 修改 a 或 b,觸發(fā) watch 回調(diào)
a.value = 1; // 輸出:a 從 0 變?yōu)?1,b 從 0 變?yōu)?0
b.value = 2; // 輸出:a 從 1 變?yōu)?1,b 從 0 變?yōu)?2
- 偵聽 reactive 對象的屬性
import { reactive, watch } from 'vue';
const state = reactive({ count: 0, name: 'Vue' });
// 偵聽 state.count 的變化
watch(
() => state.count,
(newVal, oldVal) => {
console.log(`count 從 ${oldVal} 變?yōu)?${newVal}`);
}
);
// 修改 state.count,觸發(fā) watch 回調(diào)
state.count = 1; // 輸出:count 從 0 變?yōu)?1
- 深度偵聽 reactive 對象
import { reactive, watch } from 'vue';
const state = reactive({
user: { name: 'Vue', age: 3 }
});
// 深度偵聽 state.user 的變化
watch(
() => state.user,
(newVal, oldVal) => {
console.log('user 對象發(fā)生變化', newVal);
},
{ deep: true } // 開啟深度偵聽
);
// 修改 state.user.age,觸發(fā) watch 回調(diào)
state.user.age = 4; // 輸出:user 對象發(fā)生變化 { name: 'Vue', age: 4 }
- 立即執(zhí)行 watch
import { ref, watch } from 'vue';
const count = ref(0); 、
// 立即執(zhí)行 watch(組件掛載時執(zhí)行一次)
watch(
count,
(newVal, oldVal) => {
console.log(`count 當前值為 ${newVal}`);
},
{ immediate: true } // 開啟立即執(zhí)行
);
// 輸出:count 當前值為 0
watchEffect使用
watchEffect 用于隱式偵聽回調(diào)函數(shù)內(nèi)部的響應(yīng)式依賴,當任何依賴變化時執(zhí)行回調(diào)函數(shù)。
- 基本使用
import { ref, watchEffect } from 'vue';
const count = ref(0);
const name = ref('Vue');
// 隱式偵聽 count 和 name 的變化
watchEffect(() => {
console.log(`count: ${count.value}, name: ${name.value}`);
});
// 輸出:count: 0, name: Vue
// 修改 count,觸發(fā) watchEffect 回調(diào)
count.value = 1; // 輸出:count: 1, name: Vue
// 修改 name,觸發(fā) watchEffect 回調(diào)
name.value = 'React'; // 輸出:count: 1, name: React
- 停止偵聽
import { ref, watchEffect } from 'vue';
const count = ref(0);
// 停止偵聽
const stop = watchEffect(() => {
console.log(`count: ${count.value}`);
});
// 修改 count,觸發(fā) watchEffect 回調(diào)
count.value = 1; // 輸出:count: 1
// 停止偵聽
stop();
// 修改 count,不再觸發(fā) watchEffect 回調(diào)
count.value = 2; // 無輸出
- 清除副作用
watchEffect 支持清除副作用(如取消數(shù)據(jù)請求、清除定時器等)。
import { ref, watchEffect } from 'vue';
const id = ref(0);
watchEffect((onInvalidate) => {
// 模擬數(shù)據(jù)請求
const timer = setTimeout(() => {
console.log(`請求數(shù)據(jù),id: ${id.value}`);
}, 1000);
// 清除副作用(組件卸載或依賴變化時執(zhí)行)
onInvalidate(() => {
clearTimeout(timer);
console.log('清除定時器');
});
});
// 修改 id,觸發(fā) watchEffect 回調(diào)
id.value = 1;
// 輸出:清除定時器,然后 1 秒后輸出:請求數(shù)據(jù),id: 1
總結(jié)
- watch:適用于需要顯式偵聽特定數(shù)據(jù)源,并需要知道數(shù)據(jù)變化前后值的場景。
- watchEffect:適用于需要根據(jù)多個依賴執(zhí)行副作用,且不需要關(guān)心數(shù)據(jù)變化前后值的場景。
在實際開發(fā)中,應(yīng)根據(jù)具體需求選擇合適的偵聽器:
- 如果需要偵聽特定數(shù)據(jù)的變化并獲取新舊值,使用
watch。 - 如果需要根據(jù)多個依賴執(zhí)行副作用(如數(shù)據(jù)請求),使用
watchEffect。
到此這篇關(guān)于Vue偵聽器:watch與watchEffect的區(qū)別與使用的文章就介紹到這了,更多相關(guān)Vue :watch與watchEffect內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- Vue3 watchEffect核心用法與原理解析
- Vue3中watch與watchEffect使用方法詳解
- Vue.js中watchEffect的異步問題及解決方案
- vue3中WatchEffect高級偵聽器的實現(xiàn)
- Vue3?watchEffect的使用教程和相關(guān)概念
- Vue3中watchEffect高級偵聽器的具體使用
- Vue3.0監(jiān)聽器watch與watchEffect詳解
- Vue中watch與watchEffect的區(qū)別詳細解讀
- Vue3中watchEffect和watch的基礎(chǔ)應(yīng)用詳解
- vue3中watch和watchEffect的區(qū)別
- 詳解Vue3?中的watchEffect?特性
- Vue WatchEffect函數(shù)創(chuàng)建高級偵聽器
相關(guān)文章
vuex?mutations的兩種調(diào)用方法小結(jié)
這篇文章主要介紹了vuex?mutations的兩種調(diào)用方法小結(jié),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-03-03
解決vue的變量在settimeout內(nèi)部效果失效的問題
今天小編就為大家分享一篇解決vue的變量在settimeout內(nèi)部效果失效的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-08-08
vue實現(xiàn)導航欄效果(選中狀態(tài)刷新不消失)
這篇文章主要為大家詳細介紹了vue實現(xiàn)導航欄效果,選中狀態(tài)刷新不消失,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-12-12

