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

