Vue3中Watch、Watcheffect、Computed的使用和區(qū)別解析
Vue3–Watch、Watcheffect、Computed的使用和區(qū)別
一、watch
1.功能
watch 用于監(jiān)聽(tīng)響應(yīng)式數(shù)據(jù)的變化,并在數(shù)據(jù)變化時(shí)執(zhí)行特定的回調(diào)函數(shù)。適合在響應(yīng)式數(shù)據(jù)變化時(shí)執(zhí)行異步操作或復(fù)雜邏輯。
2.主要特點(diǎn)
- 指定數(shù)據(jù)監(jiān)聽(tīng):可以精確地監(jiān)聽(tīng)一個(gè)或多個(gè)響應(yīng)式數(shù)據(jù)。
- 回調(diào)函數(shù):數(shù)據(jù)變化時(shí)調(diào)用指定的回調(diào)函數(shù),并傳入新值和舊值。
- 配置項(xiàng):支持
immediate(是否立即執(zhí)行回調(diào))和deep(是否深度監(jiān)聽(tīng))配置。
3.典型應(yīng)用場(chǎng)景
- 需要執(zhí)行異步操作(如 API 請(qǐng)求)。
- 需要執(zhí)行復(fù)雜的副作用操作。
- 需要監(jiān)聽(tīng)深層次的對(duì)象變化。
import { ref, watch } from 'vue';
const count = ref(0);
watch(count, (newValue, oldValue) => {
console.log(`依賴值改變${oldValue} -- ${newValue}`);
}, { immediate: true, deep: false });4.參數(shù)介紹
- 第一個(gè)參數(shù):需要監(jiān)聽(tīng)的響應(yīng)式數(shù)據(jù)或 getter 函數(shù)。
- 第二個(gè)參數(shù):回調(diào)函數(shù),接受新值和舊值作為參數(shù)。
- 第三個(gè)參數(shù)(可選):配置項(xiàng),包括
immediate和deep。
5.基本使用示例(父子組件結(jié)合ElementUI)
父組件
<template>
<div>
<!-- 使用 ElementUI 的 el-input 組件輸入內(nèi)容 -->
<el-input v-model="parentInput" placeholder="Enter something"></el-input>
<!-- 將輸入內(nèi)容傳遞給子組件 -->
<ChildComponent :inputValue="parentInput" />
</div>
</template>
<script setup>
import { ref } from 'vue';
import ChildComponent from './ChildComponent.vue';
// 創(chuàng)建一個(gè)響應(yīng)式變量 parentInput,用于存儲(chǔ)輸入內(nèi)容
const parentInput = ref('');
</script>子組件
<template>
<div>
<!-- 顯示父組件傳遞的輸入內(nèi)容 -->
<p>父組件輸入: {{ inputValue }}</p>
</div>
</template>
<script setup>
import { watch, toRefs } from 'vue';
// 定義 props 接收父組件傳遞的數(shù)據(jù)
const props = defineProps({
inputValue: String,
});
// 解構(gòu) props
const { inputValue } = toRefs(props);
// 監(jiān)聽(tīng) inputValue 的變化,并在變化時(shí)執(zhí)行回調(diào)
watch(inputValue, (newValue) => {
console.log(`父組件輸入改變: ${newValue}`);
});
</script>6.常見(jiàn)用法
1. 監(jiān)聽(tīng)單個(gè)響應(yīng)式數(shù)據(jù)
import { ref, watch } from 'vue';
const count = ref(0);
watch(count, (newValue, oldValue) => {
console.log(`count值改變 ${oldValue} -- ${newValue}`);
});2. 監(jiān)聽(tīng)多個(gè)響應(yīng)式數(shù)據(jù)
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}`);
console.log(`count2值改變 ${oldCount2} -- ${newCount2}`);
});3. 深度監(jiān)聽(tīng)對(duì)象{ deep: true }
import { ref, watch } from 'vue';
const person = ref({ name: 'John', age: 30 });
watch(person, (newPerson, oldPerson) => {
console.log(`Person改變 ${oldPerson.name} -- ${newPerson.name}`);
}, { deep: true });4. 立即執(zhí)行回調(diào){ immediate: true }
import { ref, watch } from 'vue';
const count = ref(0);
watch(count, (newValue, oldValue) => {
console.log(`count值改變 ${oldValue} -- ${newValue}`);
}, { immediate: true });5. 監(jiān)聽(tīng) getter 函數(shù)
import { ref, watch } from 'vue';
const count = ref(0);
// 使用 watch 監(jiān)聽(tīng)一個(gè) getter 函數(shù)
watch(
// 第一個(gè)參數(shù)是一個(gè) getter 函數(shù),該函數(shù)返回我們要監(jiān)聽(tīng)的計(jì)算值
() => count.value + 1,
// 第二個(gè)參數(shù)是回調(diào)函數(shù),當(dāng) getter 函數(shù)的返回值發(fā)生變化時(shí),該回調(diào)函數(shù)會(huì)被調(diào)用
(newValue, oldValue) => {
// 打印舊值和新值
console.log(`Computed值改變 ${oldValue} -- ${newValue}`);
}
);二、watchEffect
1.功能
watchEffect 用于自動(dòng)運(yùn)行一個(gè)副作用函數(shù),并追蹤其依賴。任何依賴變化時(shí)都會(huì)重新運(yùn)行該函數(shù)。適合用來(lái)執(zhí)行副作用,但不需要明確指定依賴。
2.主要特點(diǎn)
- 自動(dòng)依賴追蹤:自動(dòng)追蹤副作用函數(shù)中的響應(yīng)式數(shù)據(jù)依賴。
- 立即執(zhí)行:函數(shù)會(huì)立即執(zhí)行一次,并在依賴變化時(shí)重新執(zhí)行。
- 簡(jiǎn)潔性:不需要手動(dòng)指定依賴,代碼更簡(jiǎn)潔。
3.典型應(yīng)用場(chǎng)景
- 需要自動(dòng)運(yùn)行副作用函數(shù),并自動(dòng)管理依賴。
- 界面更新或 DOM 操作。
import { ref, watchEffect } from 'vue';
const count = ref(0);
watchEffect(() => {
console.log(`count: ${count.value}`);
}, { flush: 'pre' });4.參數(shù)介紹
- 第一個(gè)參數(shù):副作用函數(shù)。
- 第二個(gè)參數(shù)(可選):配置項(xiàng),包括
flush。
watchEffect 的 flush 選項(xiàng)用于控制副作用函數(shù)的觸發(fā)時(shí)機(jī)。flush 選項(xiàng)有三種可能的值:
pre:在組件更新前觸發(fā)(這是默認(rèn)值)。post:在組件更新后觸發(fā)。sync:同步地觸發(fā)。
flush: ‘pre’
默認(rèn)情況下,watchEffect 會(huì)在組件更新之前運(yùn)行副作用函數(shù)。這意味著當(dāng)響應(yīng)式數(shù)據(jù)變化時(shí),副作用會(huì)在 DOM 更新前執(zhí)行。
flush: ‘post’
將 flush 設(shè)置為 'post' 可以在組件更新后觸發(fā)副作用函數(shù)。這對(duì)于那些需要訪問(wèn)更新后的 DOM 元素的副作用來(lái)說(shuō)很有用。
flush: ‘sync’
將 flush 設(shè)置為 'sync' 可以使副作用同步觸發(fā),而不是等到下一個(gè)微任務(wù)隊(duì)列。這意味著副作用會(huì)立即在響應(yīng)式數(shù)據(jù)變化時(shí)執(zhí)行。
import { ref, watchEffect } from 'vue';
const count = ref(0);
// 默認(rèn) flush: 'pre'
watchEffect(() => {
console.log(`count (pre): ${count.value}`);
});
// flush: 'post'
watchEffect(() => {
console.log(`count (post): ${count.value}`);
}, { flush: 'post' });
// flush: 'sync'
watchEffect(() => {
console.log(`count (sync): ${count.value}`);
}, { flush: 'sync' });
count.value++;三個(gè) watchEffect 會(huì)在不同的時(shí)機(jī)記錄 count 的值:
flush: 'pre'會(huì)在 DOM 更新前執(zhí)行。flush: 'post'會(huì)在 DOM 更新后執(zhí)行。flush: 'sync'會(huì)同步執(zhí)行。
5.基本使用示例(父子組件結(jié)合ElementUI)
父組件
<template>
<div>
<!-- 使用 ElementUI 的 el-slider 組件輸入數(shù)值 -->
<el-slider v-model="sliderValue"></el-slider>
<!-- 將滑動(dòng)條的值傳遞給子組件 -->
<ChildComponent :sliderValue="sliderValue" />
</div>
</template>
<script setup>
import { ref } from 'vue';
import ChildComponent from './ChildComponent.vue';
// 創(chuàng)建一個(gè)響應(yīng)式變量 sliderValue,用于存儲(chǔ)滑動(dòng)條的值
const sliderValue = ref(50);
</script>子組件
<template>
<div>
<!-- 顯示父組件傳遞的滑動(dòng)條的值 -->
<p>Slider value: {{ sliderValue }}</p>
</div>
</template>
<script setup>
import { watchEffect, toRefs } from 'vue';
// 定義 props 接收父組件傳遞的數(shù)據(jù)
const props = defineProps({
sliderValue: Number,
});
// 解構(gòu) props
const { sliderValue } = toRefs(props);
// 監(jiān)聽(tīng) sliderValue 的變化,并在變化時(shí)執(zhí)行副作用函數(shù)
watchEffect(() => {
console.log(`Slider: ${sliderValue.value}`);
});
</script>6.常見(jiàn)用法
1. 基本用法
import { ref, watchEffect } from 'vue';
const count = ref(0);
watchEffect(() => {
console.log(`count: ${count.value}`);
});2. 取消副作用
import { ref, watchEffect } from 'vue';
const count = ref(0);
const stop = watchEffect(() => {
console.log(`count: ${count.value}`);
});
// 停止副作用
stop();3. 延遲執(zhí)行{ flush: ‘post’ }
import { ref, watchEffect } from 'vue';
const count = ref(0);
watchEffect(() => {
console.log(`count: ${count.value}`);
}, { flush: 'post' });4. 自定義調(diào)度
import { ref, watchEffect } from 'vue';
const count = ref(0);
// 使用 watchEffect 自動(dòng)追蹤副作用
watchEffect(
() => {
// 這個(gè)函數(shù)在 count 發(fā)生變化時(shí)會(huì)被調(diào)用
console.log(`count: ${count.value}`);
},
{
// 配置項(xiàng):onTrack 和 onTrigger 是調(diào)試鉤子
// onTrack 會(huì)在副作用追蹤依賴時(shí)調(diào)用
onTrack(e) {
console.log('tracked', e);
},
// onTrigger 會(huì)在依賴變化導(dǎo)致副作用重新執(zhí)行時(shí)調(diào)用
onTrigger(e) {
console.log('triggered', e);
}
}
);三、computed
1.功能
computed 用于聲明計(jì)算屬性,計(jì)算屬性會(huì)根據(jù)其依賴的響應(yīng)式數(shù)據(jù)自動(dòng)更新,并且具有緩存特性。適合計(jì)算派生狀態(tài)或數(shù)據(jù)。
2.主要特點(diǎn)
- 依賴管理:計(jì)算屬性根據(jù)依賴的響應(yīng)式數(shù)據(jù)自動(dòng)更新。
- 緩存:只有當(dāng)依賴的數(shù)據(jù)變化時(shí),計(jì)算屬性才會(huì)重新計(jì)算。
- 簡(jiǎn)潔性:聲明式地定義派生數(shù)據(jù),代碼簡(jiǎn)潔且易于維護(hù)。
3.典型應(yīng)用場(chǎng)景
- 需要根據(jù)其他響應(yīng)式數(shù)據(jù)派生出新的數(shù)據(jù)。
- 需要高效的、緩存的計(jì)算屬性。
import { ref, computed } from 'vue';
const count = ref(0);
const doubleCount = computed(() => count.value * 2);4.參數(shù)介紹
- 第一個(gè)參數(shù):getter 函數(shù),返回計(jì)算屬性的值。
- 第二個(gè)參數(shù)(可選):setter 函數(shù),用于設(shè)置計(jì)算屬性的值(可寫計(jì)算屬性)。
5.基本使用示例(父子組件結(jié)合ElementUI)
父組件
<template>
<div>
<!-- 使用 ElementUI 的 el-input 組件輸入數(shù)值 -->
<el-input v-model="inputValue" placeholder="Enter a number"></el-input>
<!-- 將輸入的數(shù)值傳遞給子組件 -->
<ChildComponent :number="inputValue" />
</div>
</template>
<script setup>
import { ref } from 'vue';
import ChildComponent from './ChildComponent.vue';
// 創(chuàng)建一個(gè)響應(yīng)式變量 inputValue,用于存儲(chǔ)輸入的數(shù)值
const inputValue = ref(0);
</script>子組件
<template>
<div>
<!-- 顯示父組件傳遞的數(shù)值的平方 -->
<p>Squared value: {{ squaredNumber }}</p>
</div>
</template>
<script setup>
import { computed, toRefs } from 'vue';
// 定義 props 接收父組件傳遞的數(shù)據(jù)
const props = defineProps({
number: Number,
});
// 解構(gòu) props
const { number } = toRefs(props);
// 創(chuàng)建一個(gè)計(jì)算屬性 squaredNumber,計(jì)算 number 的平方
const squaredNumber = computed(() => number.value * number.value);
</script>6.常見(jiàn)用法
1. 基本用法
import { ref, computed } from 'vue';
const count = ref(0);
const doubleCount = computed(() => count.value * 2);2. 可寫計(jì)算屬性 (get set)
import { ref, computed } from 'vue';
const firstName = ref('John');
const lastName = ref('Doe');
const fullName = computed({
get: () => `${firstName.value} ${lastName.value}`,
set: (newValue) => {
const names = newValue.split(' ');
firstName.value = names[0];
lastName.value = names[1];
},
});3. 依賴其他計(jì)算屬性
import { ref, computed } from 'vue';
const count = ref(0);
const doubleCount = computed(() => count.value * 2);
const tripleCount = computed(() => doubleCount.value * 1.5);4. 使用在模板中
<template>
<div>{{ doubleCount }}</div>
</template>
<script setup>
import { ref, computed } from 'vue';
const count = ref(0);
const doubleCount = computed(() => count.value * 2);
</script>5. 配合 watch 使用
import { ref, computed, watch } from 'vue';
const count = ref(0);
const doubleCount = computed(() => count.value * 2);
watch(doubleCount, (newValue) => {
console.log(`doubleCount: ${newValue}`);
});6. 配合 watchEffect 使用
import { ref, computed, watchEffect } from 'vue';
const count = ref(0);
const doubleCount = computed(() => count.value * 2);
watchEffect(() => {
console.log(`doubleCount: ${doubleCount.value}`);
});四、總結(jié)與區(qū)別
watch 的多種用法
- 監(jiān)聽(tīng)單個(gè)響應(yīng)式數(shù)據(jù)。
- 監(jiān)聽(tīng)多個(gè)響應(yīng)式數(shù)據(jù)。
- 深度監(jiān)聽(tīng)對(duì)象。{ deep: true }
- 立即執(zhí)行回調(diào)。{ immediate: true }
- 監(jiān)聽(tīng) getter 函數(shù)。
watchEffect 的多種用法
- 基本用法。
- 取消副作用。
- 延遲執(zhí)行。{ flush: ‘post’ }
- 自定義調(diào)度。
computed 的多種用法
- 基本用法。
- 可寫計(jì)算屬性。 (get set)依賴其他計(jì)算屬性。使
- 用在模板中。
- 配合
watch使用。 - 配合
watchEffect使用。
區(qū)別
| 特性 | watch | watchEffect | computed |
|---|---|---|---|
| 功能 | 監(jiān)聽(tīng)響應(yīng)式數(shù)據(jù)變化并執(zhí)行回調(diào) | 自動(dòng)運(yùn)行副作用函數(shù)并追蹤依賴 | 聲明計(jì)算屬性,根據(jù)依賴自動(dòng)更新并緩存 |
| 依賴管理 | 手動(dòng)指定 | 自動(dòng)追蹤 | 自動(dòng)管理 |
| 緩存 | 無(wú) | 無(wú) | 有 |
| 適用場(chǎng)景 | 異步操作、復(fù)雜副作用、深度監(jiān)聽(tīng) | 界面更新、副作用函數(shù) | 派生狀態(tài)、數(shù)據(jù)計(jì)算 |
| 優(yōu)點(diǎn) | 精確控制、支持異步操作 | 自動(dòng)依賴追蹤、代碼簡(jiǎn)潔 | 聲明式、自動(dòng)更新、緩存 |
| 缺點(diǎn) | 需要手動(dòng)指定依賴、代碼相對(duì)復(fù)雜 | 每次依賴變化時(shí)都會(huì)重新執(zhí)行副作用函數(shù) | 需要在創(chuàng)建時(shí)指定依賴,無(wú)法動(dòng)態(tài)改變計(jì)算邏輯 |
Watch、Watcheffect、Computed三種方法各有優(yōu)劣,選擇使用哪種方法主要取決于具體的應(yīng)用場(chǎng)景和需求。watch 適合復(fù)雜的副作用操作,watchEffect 適合簡(jiǎn)單的自動(dòng)副作用管理,而 computed 適合聲明式的派生狀態(tài)計(jì)算。
到此這篇關(guān)于Vue3中Watch、Watcheffect、Computed的使用和區(qū)別解析的文章就介紹到這了,更多相關(guān)Vue3--Watch、Watcheffect、Computed內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- vue3 watch和watchEffect的使用以及有哪些區(qū)別
- Vue3.0監(jiān)聽(tīng)器watch與watchEffect詳解
- vue3中的watch和watchEffect實(shí)例詳解
- 淺談Vue3中watchEffect的具體用法
- Vue3?中?watch?與?watchEffect?區(qū)別及用法小結(jié)
- Vue3中watchEffect高級(jí)偵聽(tīng)器的具體使用
- VUE3中watch和watchEffect的用法詳解
- 一文搞懂Vue3中watchEffect偵聽(tīng)器的使用
- Vue3中watchEffect和watch的基礎(chǔ)應(yīng)用詳解
- Vue3中watch與watchEffect使用方法詳解
相關(guān)文章
vue中手機(jī)號(hào),郵箱正則驗(yàn)證以及60s發(fā)送驗(yàn)證碼的實(shí)例
下面小編就為大家分享一篇vue中手機(jī)號(hào),郵箱正則驗(yàn)證以及60s發(fā)送驗(yàn)證碼的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-03-03
淺談Vue.js 關(guān)于頁(yè)面加載完成后執(zhí)行一個(gè)方法的問(wèn)題
這篇文章主要介紹了Vue.js 關(guān)于頁(yè)面加載完成后執(zhí)行一個(gè)方法的問(wèn)題,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-04-04
vue3+element?Plus實(shí)現(xiàn)表格前端分頁(yè)完整示例
這篇文章主要給大家介紹了關(guān)于vue3+element?Plus實(shí)現(xiàn)表格前端分頁(yè)的相關(guān)資料,雖然很多時(shí)候后端會(huì)把分頁(yè),搜索,排序都做好,但是有些返回?cái)?shù)據(jù)并不多的頁(yè)面,或者其他原因不能后端分頁(yè)的通常會(huì)前端處理,需要的朋友可以參考下2023-08-08
手把手教你如何運(yùn)行一個(gè)前端uniapp項(xiàng)目
這篇文章主要介紹了如何設(shè)置和運(yùn)行一個(gè)基于uni-app框架的項(xiàng)目,包括安裝必要的軟件、克隆項(xiàng)目并安裝依賴,以及如何使用HBuilderX進(jìn)行項(xiàng)目運(yùn)行和調(diào)試,需要的朋友可以參考下2025-01-01
vue elementUI select下拉框如何設(shè)置默認(rèn)值
這篇文章主要介紹了vue elementUI select下拉框如何設(shè)置默認(rèn)值問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-10-10
vue+moment實(shí)現(xiàn)倒計(jì)時(shí)效果
這篇文章主要為大家詳細(xì)介紹了vue+moment實(shí)現(xiàn)倒計(jì)時(shí)效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-08-08
vue-cli啟動(dòng)本地服務(wù)局域網(wǎng)不能訪問(wèn)的原因分析
這篇文章主要介紹了vue-cli啟動(dòng)本地服務(wù),局域網(wǎng)下訪問(wèn)不到的原因分析,在文中還給大家介紹了vue-cli起的webpack項(xiàng)目 用localhost可以訪問(wèn),但是切換到ip就不可以訪問(wèn) 的原因,本文給大家介紹的非常詳細(xì),需要的朋友參考下2018-01-01
記錄--使用el-time-picker默認(rèn)值遇到的問(wèn)題
這篇文章主要介紹了記錄--使用el-time-picker默認(rèn)值遇到的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-09-09

