vue3監聽屬性watch和watchEffect的詳解

文章目錄

  • 1. 前言
  • 2. 常規用法
  • 3. 監聽對象和route變化
  • 4. 使用場景
      • 4.1 即時表單驗證
      • 4.2 搜索聯想功能
      • 4.3 數據變化聯動處理
  • 5. watchEffect詳解
    • 5-1 基本概念
    • 5-2 核心用法
      • 基礎示例:自動響應依賴變化
      • 處理異步副作用
      • 停止監聽與清理副作用
    • 5-3 高級場景應用
      • 監聽多個響應式依賴
      • 處理 DOM 副作用
  • 6. watch與watchEffect的對比
    • 選擇建議:

1. 前言

在 Vue3 中,watch 是一個獨立的函數,用于響應式地監聽數據變化并執行回調。與 Vue2 的選項式 API 不同,Vue3 的 watch 主要在 Composition API 中使用,需要從 @vue/composition-api 或 Vue3 核心包中導入。它接收三個參數:監聽的數據源、回調函數和可選的配置對象。

Vue3 的 watch 具有以下特點:

  • 更靈活的監聽方式,支持監聽 ref、reactive 對象和函數返回值
  • 明確的依賴聲明,避免依賴收集問題
  • 更強大的配置選項,如深度監聽、立即執行等

2. 常規用法

在 Vue3 中使用 watch 需要先導入相關函數,通常在 setup 函數中使用。watch 第一個參數可以是 ref 類型的數據、響應式對象的屬性,或者一個返回值的函數。回調函數接收新值和舊值作為參數。

<template><div class="home_box"><h1>{{ total }}</h1><button @click="handleAddTotal">增加</button></div>
</template><script>
import { ref, watch } from 'vue';export default {name: 'Home',setup() {const total = ref(0);// 常規監聽 ref 類型數據watch(total, (newValue, oldValue) => {console.log('舊值:', oldValue);console.log('新值:', newValue);});const handleAddTotal = () => {total.value++;};return {total,handleAddTotal};}
}
</script>

3. 監聽對象和route變化

Vue3 的 watch 可以監聽多種類型的數據,包括響應式對象、嵌套屬性和路由變化。對于對象類型的監聽,需要注意深度監聽的配置;對于路由變化,需要使用特定的監聽方式。

<template><div class="home_box"><!-- 頁面內容 --></div>
</template><script>
import { ref, reactive, watch } from 'vue';
import { useRoute } from 'vue-router';export default {name: 'Home',setup() {// 基本類型const aaa = ref(0);// 響應式對象const state = reactive({bbb: 0,ccc: {c1: 0,c2: 0},ddd: {d1: 0,d2: {d21: 0}}});// 獲取路由實例const route = useRoute();// 監聽基本類型watch(aaa, (newValue, oldValue) => {console.log('aaa 舊值:', oldValue);console.log('aaa 新值:', newValue);});// 監聽基本類型,初始化立即執行watch(() => state.bbb, (newValue, oldValue) => {console.log('bbb 舊值:', oldValue);console.log('bbb 新值:', newValue);}, { immediate: true });// 監聽對象,需要深度監聽watch(() => state.ccc, (newValue, oldValue) => {console.log('ccc 舊值:', oldValue);console.log('ccc 新值:', newValue);}, { deep: true });// 監聽對象嵌套屬性watch(() => state.ddd.d2.d21, (newValue, oldValue) => {console.log('d21 舊值:', oldValue);console.log('d21 新值:', newValue);});// 監聽路由變化watch(() => route.path, (newPath, oldPath) => {console.log('路由舊路徑:', oldPath);console.log('路由新路徑:', newPath);});return {aaa,state};}
}
</script>

4. 使用場景

Vue3 的 watch 在很多場景中都有重要應用,特別是在需要響應數據變化并執行副作用的場景中。以下是幾個典型使用場景:

4.1 即時表單驗證

<template><div class="home_box"><input type="text" v-model="username"><div v-if="validationError" class="error-message">{{ validationError }}</div></div>
</template><script>
import { ref, watch } from 'vue';export default {name: 'FormValidation',setup() {const username = ref('');const validationError = ref('');// 監聽輸入框內容變化,即時驗證watch(username, (newValue) => {if (newValue.length < 3) {validationError.value = '用戶名至少需要3個字符';} else if (newValue.length > 20) {validationError.value = '用戶名不能超過20個字符';} else {validationError.value = '';}});return {username,validationError};}
}
</script>

4.2 搜索聯想功能

<template><div class="home_box"><input type="text" v-model="searchKeyword"><div v-if="searchResults.length > 0" class="suggestions"><div v-for="result in searchResults" :key="result">{{ result }}</div></div></div>
</template><script>
import { ref, watch } from 'vue';export default {name: 'SearchSuggestions',setup() {const searchKeyword = ref('');const searchResults = ref([]);// 監聽搜索關鍵詞變化,延遲發送請求let searchTimeout;watch(searchKeyword, (newValue) => {if (newValue.length < 2) {searchResults.value = [];return;}// 防抖處理,避免頻繁請求clearTimeout(searchTimeout);searchTimeout = setTimeout(() => {// 模擬API請求searchResults.value = [`${newValue} 相關結果1`,`${newValue} 相關結果2`,`${newValue} 相關結果3`];}, 500);});return {searchKeyword,searchResults};}
}
</script>

4.3 數據變化聯動處理

<template><div class="home_box"><div><label>寬度:</label><input type="number" v-model="width"></div><div><label>高度:</label><input type="number" v-model="height"></div><div>面積:{{ area }}</div></div>
</template><script>
import { ref, watch } from 'vue';export default {name: 'DimensionCalculator',setup() {const width = ref(10);const height = ref(20);const area = ref(0);// 監聽寬度和高度變化,計算面積watch([width, height], ([newWidth, newHeight]) => {area.value = newWidth * newHeight;});return {width,height,area};}
}
</script>

5. watchEffect詳解

5-1 基本概念

watchEffect 是 Vue3 中 Composition API 提供的響應式副作用監聽函數,與 watch 的主動監聽不同,它會自動追蹤回調函數中使用的響應式依賴,當依賴變化時觸發回調。其核心特點包括:

  • 自動依賴收集:無需顯式聲明監聽目標,回調內使用的響應式數據會被自動追蹤
  • 初始化立即執行:默認在組件掛載后立即執行一次回調,用于處理初始依賴的副作用
  • 簡潔的語法:適用于依賴多個響應式數據的場景,避免重復聲明監聽源

5-2 核心用法

基礎示例:自動響應依賴變化

<template><div class="home_box"><h3>計數器:{{ count }}</h3><h3>翻倍值:{{ doubleCount }}</h3><button @click="count++">+1</button></div>
</template><script>
import { ref, watchEffect } from 'vue';export default {name: 'WatchEffectDemo',setup() {const count = ref(0);const doubleCount = ref(0);// watchEffect 會自動監聽 count 的變化watchEffect(() => {console.log('依賴變化觸發回調');doubleCount.value = count.value * 2;});// 初始化時立即輸出// 控制臺打印:依賴變化觸發回調return {count,doubleCount};}
}
</script>

處理異步副作用

<template><div class="home_box"><input v-model="searchText" placeholder="搜索..."><div v-if="loading">加載中...</div><div v-else-if="searchResults.length > 0"><ul><li v-for="item in searchResults" :key="item">{{ item }}</li></ul></div><div v-else>無搜索結果</div></div>
</template><script>
import { ref, watchEffect } from 'vue';export default {name: 'SearchEffect',setup() {const searchText = ref('');const searchResults = ref([]);const loading = ref(false);watchEffect(async onInvalidate => {// 當 searchText 變化時,先清除之前的定時器let timeout;onInvalidate(() => clearTimeout(timeout));if (searchText.value.length < 2) {searchResults.value = [];return;}loading.value = true;// 模擬異步搜索timeout = setTimeout(async () => {try {// 模擬API請求const response = await new Promise(resolve => {setTimeout(() => {resolve([`${searchText.value} 結果1`,`${searchText.value} 結果2`,`${searchText.value} 結果3`]);}, 500);});searchResults.value = response;} catch (error) {console.error('搜索失敗', error);} finally {loading.value = false;}}, 300);});return {searchText,searchResults,loading};}
}
</script>

停止監聽與清理副作用

<template><div class="home_box"><button @click="toggleWatch">{{ isWatching ? '停止監聽' : '開始監聽' }}</button><div>計數器:{{ count }}</div></div>
</template><script>
import { ref, watchEffect } from 'vue';export default {name: 'WatchEffectControl',setup() {const count = ref(0);const isWatching = ref(true);let watcher = null;// 條件性創建 watchEffectconst toggleWatch = () => {if (isWatching.value) {// 啟動監聽watcher = watchEffect(() => {console.log('監聽中,count:', count.value);});} else {// 停止監聽watcher && watcher();}isWatching.value = !isWatching.value;};return {count,isWatching,toggleWatch};}
}
</script>

5-3 高級場景應用

監聽多個響應式依賴

<template><div class="home_box"><div><label>寬度:</label><input type="number" v-model="width"></div><div><label>高度:</label><input type="number" v-model="height"></div><div>面積:{{ area }}</div><div>周長:{{ perimeter }}</div></div>
</template><script>
import { ref, watchEffect } from 'vue';export default {name: 'DimensionCalculator',setup() {const width = ref(10);const height = ref(20);const area = ref(0);const perimeter = ref(0);// 同時監聽 width 和 height 的變化watchEffect(() => {area.value = width.value * height.value;perimeter.value = 2 * (width.value + height.value);});return {width,height,area,perimeter};}
}
</script>

處理 DOM 副作用

<template><div class="home_box" ref="container"><h3>滾動位置:{{ scrollY }}</h3></div>
</template><script>
import { ref, onMounted, watchEffect } from 'vue';export default {name: 'ScrollEffect',setup() {const container = ref(null);const scrollY = ref(0);onMounted(() => {// 監聽容器滾動事件watchEffect(onInvalidate => {if (!container.value) return;const handleScroll = () => {scrollY.value = container.value.scrollTop;};container.value.addEventListener('scroll', handleScroll);// 組件卸載或依賴變化時清理事件onInvalidate(() => {container.value.removeEventListener('scroll', handleScroll);});});});return {container,scrollY};}
}
</script>

6. watch與watchEffect的對比

特性watchwatchEffect
依賴聲明方式顯式指定監聽的數據源(ref、reactive 屬性、函數返回值)隱式收集回調函數中使用的響應式依賴
初始化執行默認不執行,需通過 immediate: true 配置初始化時立即執行一次
回調參數接收新值和舊值 (newValue, oldValue)不接收參數,通過閉包訪問最新值
適用場景監聽特定數據的變化,需要獲取新舊值對比處理與多個響應式數據相關的副作用,無需明確依賴
性能優化可精確控制監聽目標,避免無效觸發依賴收集可能包含不必要的響應式數據,需注意副作用清理
語法復雜度語法相對繁瑣,需聲明監聽源和配置項語法簡潔,適合快速實現響應式副作用
異步處理更適合處理需要等待特定數據變化的異步操作適合處理隨依賴變化自動更新的異步副作用(如API請求、DOM操作)

選擇建議:

  • 使用 watch
    • 需要明確知道監聽的數據源
    • 只在特定數據變化時執行回調
    • 需要獲取變化前后的新舊值對比
  • 使用 watchEffect
    • 處理與多個響應式數據相關的副作用
    • 初始化時需要立即執行一次副作用
    • 希望以更簡潔的方式實現響應式邏輯
// 場景:監聽用戶登錄狀態并請求用戶數據
setup() {const isLoggedIn = ref(false);const userData = ref(null);// 使用 watch 監聽登錄狀態變化watch(isLoggedIn, (newVal) => {if (newVal) {fetchUserData(); // 只在登錄狀態變化時請求}});// 使用 watchEffect 自動響應視圖更新watchEffect(() => {document.title = `用戶狀態: ${isLoggedIn.value ? '已登錄' : '未登錄'}`;});
}

本次分享就到這兒啦,我是鵬多多,如果您看了覺得有幫助,歡迎評論,關注,點贊,轉發,我們下次見~

往期文章

  • vue中ref的詳解以及react的ref對比
  • css使用aspect-ratio制作4:3和9:16和1:1等等比例布局
  • Web前端頁面開發阿拉伯語種適配指南
  • flutter-使用extended_image操作圖片的加載和狀態處理以及緩存和下載
  • flutter-制作可縮放底部彈出抽屜評論區效果
  • flutter-實現Tabs吸頂的PageView效果
  • Vue2全家桶+Element搭建的PC端在線音樂網站
  • 助你上手Vue3全家桶之Vue3教程
  • 超詳細!vue組件通信的10種方式
  • 超詳細!Vuex手把手教程
  • 使用nvm管理node.js版本以及更換npm淘寶鏡像源
  • vue中利用.env文件存儲全局環境變量,以及配置vue啟動和打包命令

個人主頁

  • CSDN
  • GitHub
  • 掘金

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/910234.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/910234.shtml
英文地址,請注明出處:http://en.pswp.cn/news/910234.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Spring IoC核心實現揭秘

Spring IoC(控制反轉)的實現機制是Spring框架的核心,其本質是將對象的創建、依賴管理和生命周期控制權從應用程序代碼轉移到容器中。以下是其核心實現機制: ?? 一、核心實現步驟 配置元數據加載 容器啟動時讀取XML/注解/Java配置類,解析為BeanDefinition對象(包含類名、…

Solidity內部合約創建全解析:解鎖Web3開發新姿勢

合約創建基礎 new 關鍵字創建合約 在 Solidity 中&#xff0c;new關鍵字是創建合約實例的最基本方式&#xff0c;它就像是一個 “魔法鑰匙”&#xff0c;能夠在以太坊區塊鏈上生成一個全新的合約實例。使用new關鍵字創建合約的過程非常直觀&#xff0c;就像我們在其他編程語言…

OCR大模型,破解金融文檔處理困境,從文字識別到文字理解

金融機構在日常運營中處理海量文檔。這些文檔類型多樣&#xff0c;格式復雜&#xff0c;是業務運營的基礎。如何高效、準確地處理這些文檔&#xff0c;直接影響機構的運營效率與風險控制水平。新一代的OCR大模型技術為此提供了有效的解決方案。它提升了文檔處理的自動化程度與數…

2025.6.21筆記(2)

1.編寫一個程序&#xff0c;輸入一個整數&#xff0c;判斷它是奇數還是偶數 解題思路&#xff1a; 1.因為要判斷輸入的數是奇數還是偶數&#xff0c;所以要用到if判斷 2.判讀奇偶數&#xff1a;如果這個數%20&#xff0c;則它為偶數&#xff0c;如果這個數%2!0&#xff0c;則…

【Ambari3.0.0 部署】Step7—Mariadb初始化-適用于el8

如果有其他系統部署需求可以參考原文 https://doc.janettr.com/install/manual/ MariaDB 10 是 Ambari 及大數據平臺的常見數據庫方案。本文適配 Rocky Linux 8.10&#xff0c;涵蓋 MariaDB 10.11 推薦安裝、YUM 源配置、參數優化、初始化和安全設置&#xff0c;幫助你一步到位…

SpringBoot電腦商城項目--刪除收獲地址+熱銷排行

刪除收獲地址 1 刪除收獲地址-持久層 1.1 規劃sql語句 在刪除操作之前判斷該數據是否存在&#xff0c;判斷該條地址的歸屬是否是當前的用戶執行刪除收貨地址的操作 delete from t_address where aid? 如果用戶刪除的時默認地址&#xff0c;將剩下地址的某一條作為默認收貨地…

MIMIC-III 數據集文件簡介

文件簡介&#xff1a; 共26個文件 admissions.csv 患者入院信息&#xff08;入院時間、出院時間、入院類型、科室等&#xff09;。 callout.csv ICU 外科室請求 ICU 會診的呼叫記錄。 caregivers.csv 護理患者的醫護人員信息&#xff08;身份、角色等&#xff09;。…

UL/CE雙認證!光寶MOC3052-A雙向可控硅輸出光耦 智能家居/工業控制必備!

光寶MOC3052-A雙向可控硅輸出光耦詳解 1. 產品定位 MOC3052-A 是光寶科技&#xff08;Lite-On&#xff09;推出的 雙向可控硅驅動光耦&#xff0c;屬于光電隔離型半導體器件&#xff0c;主要用于交流負載的隔離控制&#xff0c;實現低壓控制電路&#xff08;如MCU&#xff09;…

讓沒有小窗播放的視頻網站的視頻小窗播放

讓沒有小窗播放的視頻網站的視頻小窗播放 // 視頻小窗播放控制臺腳本 // 將此代碼復制到瀏覽器控制臺運行 // 運行后&#xff0c;頁面中的視頻將添加小窗播放功能(function() {// 獲取頁面中的所有video元素const videos document.querySelectorAll(video);if (videos.length…

Linux內核在啟動過程中掛載根文件系統rootfs的過程

一、掛載根文件系統rootfs的過程&#xff1a; 1. ?初始虛擬根文件系統的掛載? 內核啟動時首先會創建并掛載一個?臨時虛擬根文件系統&#xff08;如initramfs或rootfs&#xff09;??15。該階段主要作用&#xff1a; 提供基礎的設備節點和目錄結構&#xff0c;確保內核能訪…

【LeetCode】力扣題——輪轉數組、消失的數字、數組串聯

&#x1f525;個人主頁&#xff1a;艾莉絲努力練劍 ?專欄傳送門&#xff1a;《C語言》、《數據結構與算法》、C語言刷題12天IO強訓 &#x1f349;學習方向&#xff1a;C/C方向 ??人生格言&#xff1a;為天地立心&#xff0c;為生民立命&#xff0c;為往圣繼絕學&#xff0c;…

Java Stream詳解

Java Stream詳解 Stream 是 Java 8 引入的流式數據處理工具&#xff0c;可以像流水線一樣對集合數據進行高效操作&#xff08;過濾、轉換、統計等&#xff09;。核心特點&#xff1a; 鏈式操作&#xff1a;支持多個操作串聯不修改原始數據&#xff1a;生成新結果支持并行處理…

Java回歸循環理解

一、Java循環的四種 1. 傳統for循環 - 精確控制的首選 // 遍歷數組 int[] numbers {1, 2, 3, 4, 5}; for (int i 0; i < numbers.length; i) {System.out.println(numbers[i]); }// 嵌套示例&#xff1a;矩陣遍歷 int[][] matrix {{1, 2}, {3, 4}}; for (int row 0; r…

飛騰D2000金融工控主板,點亮經濟高質量發展

近年來&#xff0c;國家不斷推出金融行業的政策和法規&#xff0c;推動金融業高質量發展。在國家大力推進金融行業改革和創新的大環境下&#xff0c;金融工控主板市場也迎來了新的發展機遇。隨著國產CPU技術的不斷突破&#xff0c;以及我國對金融安全重視程度的提高&#xff0c…

SimpleITK——創建nrrd體素模型

在介紹如何生成nrrd前&#xff0c;了解一下為什么醫學影像上一般使用nrrd的體素模型&#xff1f; 為什么醫學影像上一般使用nrrd的體素模型&#xff1f; 在醫學影像領域&#xff0c;?NRRD&#xff08;Nearly Raw Raster Data&#xff09;格式?被廣泛用于存儲體素模型&#x…

Docker容器部署KES

一、安裝部署 1&#xff0c;導入鏡像 #導入鏡像&#xff08;root用戶&#xff09; [rootnode docker ]# mv kdb_x86_64_V008R006C009B0014.tar kingbase.tar [rootnode docker]# docker load -i kingbase.tar#查看鏡像&#xff08;root用戶&#xff09; [rootnode docker]# d…

C++基礎練習 sort函數,用于排序函數

題目&#xff1a; https://acm.hdu.edu.cn/showproblem.php?pid2039 解答&#xff1a; #include <iostream> #include <cmath> #include <algorithm> using namespace std;double a[3]; int main(){int n;cin>>n;while(n--){cin>>a[0]>>…

棱鏡觀察|EMB“重構”卡鉗,車企降本壓力與Brembo困局

傳統制動卡鉗市場&#xff0c;正在迎來變革時刻。 一直以來&#xff0c;采埃孚、大陸集團、日立安斯泰莫等外資供應商占據中國乘用車卡鉗前裝市場&#xff08;包括前制動卡鉗和后集成EPB卡鉗&#xff09;的半壁江山。同時&#xff0c;伯特利、亞太股份、萬向、弗迪等中國供應商…

《顛覆傳統:CSS遮罩的圖像創意設計指南》

想象有一塊神奇的模板&#xff0c;上面有各種形狀的鏤空區域&#xff0c;當我們將這塊模板覆蓋在圖像上時&#xff0c;只有透過鏤空區域才能看到圖像的部分&#xff0c;而模板遮擋的地方則被隱藏起來&#xff0c;這便是CSS遮罩的核心概念。遮罩&#xff0c;簡單來說&#xff0c…

5.基于神經網絡的時間序列預測

近年來&#xff0c;已經開發了一些深度學習方法并將其應用于單變量時間預測場景&#xff0c;其中時間序列由在等時間增量上按順序記錄的單個觀測數據組成。 5.1 將深度學習用于時間序列預測的原因 機器學習的目標是提取特征來訓練模型。模型將輸入數據&#xff08;例如圖片&am…