14.vue.js的watch()的注意事項(1)

一、
Q :因為 state 有內部的屬性 也就是id。 因為要追逐id。所以要寫函數?而不能直接監聽state。 只監聽state ,監聽不到id的變化嗎?

A:

為什么監聽 state 不等于監聽 state.id?

在 Vue 3 中,如果你這樣寫:

watch(state, () => {
console.log(‘state changed’);
})

這 只能監聽整個 state 對象的引用是否變化,而不是它內部某個屬性的變化。

🛑 舉個例子:

const state = reactive({
id: 1,
name: ‘Tom’
});

watch(state, () => {
console.log(‘state changed’);
});

現在你執行:

state.id = 2;

?這個時候,watch 是不會觸發的!

因為 state 本身(這個對象的引用)沒變,只是它里面的屬性變了。Vue 沒法“自動猜測”你想追蹤哪些屬性。

? 正確寫法:想監聽 id,就得顯式寫 () => state.id

watch(() => state.id, (newVal, oldVal) => {
console.log(‘id changed from’, oldVal, ‘to’, newVal);
});

這樣 Vue 就知道:“哦!你只關心 state.id 的變化。”

? 如果你真的想監聽整個對象的所有屬性怎么辦?

可以用 deep: true 選項:

watch(state, (newVal, oldVal) => {
console.log(‘state deep changed’);
}, { deep: true });

但注意這性能開銷比較大,而且也不夠精確,不推薦只為了監聽某個屬性而這樣寫。

? 總結一下

在這里插入圖片描述

二、
Q:好像還有個shallowReactive什么的。可以用來做淺層和深層監聽

A:Vue 3 中確實有一套跟 “深層 / 淺層” 有關的工具,它們用來控制 響應式系統的行為,而不是直接控制 watch 的深度監聽。

我們來拆解清楚這幾個概念 👇

🧱 1. deep 是 watch 的選項

當你用 watch() 監聽一個對象時,Vue 默認只監聽它的“引用變化”,不會深層追蹤子屬性的變化。

? 用法:

watch(state, (newVal, oldVal) => {
console.log(‘deep change’);
}, { deep: true })

這個 { deep: true } 表示:Vue 會遞歸追蹤 state 內部所有的屬性變化。

🧪 舉個例子:

const state = reactive({
user: {
name: ‘Tom’,
age: 20
}
});

watch(state, () => {
console.log(‘state changed’);
}, { deep: true });

這時你做:

state.user.name = ‘Jerry’;

? 這會觸發監聽,因為你用了 deep: true。

🧊 2. shallowReactive 和 shallowRef

這是你剛剛提到的 shallow,它是另一個話題:

? 作用:只讓對象最外層變成響應式,里面嵌套的對象不會響應式化!

🔹shallowReactive 用法:

import { shallowReactive } from ‘vue’;

const state = shallowReactive({
user: {
name: ‘Tom’
}
});

這時,如果你改 state.user.name,Vue 不會追蹤到變化!

🔹對比 reactive:

const state = reactive({
user: {
name: ‘Tom’
}
});

這里 state.user.name 的變化會被 Vue 自動追蹤。

🧠 總結一下區別:

用法 深度追蹤 用途
reactive() ? 會遞歸處理內部對象 通常默認使用
shallowReactive() ? 只處理第一層,內部對象不是響應式 性能優化,避免不必要追蹤
watch(obj, fn, { deep: true }) ? 深層監聽 用于監聽嵌套對象屬性變化
watch(obj, fn) ? 默認只監聽對象引用變化 如果改屬性值,不觸發

🎯 你什么時候會用 shallowReactive?
? 當你知道你不需要監聽內部屬性,比如只監聽 API 結果是否更新,不關心結果結構。
? 或者你手動控制響應式,不希望 Vue 自動追蹤太多東西(性能優化場景)。

三、
Q:
x和y 都是ref(0)執行watch(x,()=>y.value],([newX,newY])=>{ })這什么意思? x和y的監聽有什么區別

A:
確實,從“效果”上來說,監聽 x 和監聽 () => y.value,在你這個例子中表現是一樣的。但是寫法不一樣,是因為 Vue 對 ref 和函數這兩種寫法的處理方式不同。

我們來徹底搞清楚:

? 結論先說:

雖然監聽效果一樣,但寫法上的不同是因為 Vue 對不同“源”的處理機制不一樣:

寫法 意義 Vue 的處理方式
x 是 ref 對象 Vue 自動監聽 x.value 的變化
() => y.value 是一個 getter 函數 Vue 追蹤這個函數里訪問的響應式依賴(即 y.value)

🧪 來看一組對比例子

const x = ref(1);
const y = ref(2);

watch([x, () => y.value], ([newX, newY]) => {
console.log(newX, newY);
});

你也可以這樣寫:

watch([() => x.value, () => y.value], ([newX, newY]) => {
console.log(newX, newY);
});

或者:

watch([x, y], ([newX, newY]) => {
console.log(newX, newY);
});

?? 這些寫法最終都能監聽 x.value 和 y.value 的變化。

?那為什么還要寫 () => y.value 呢?

這其實是 靈活性 + 一致性 的需要,以下場景中就必須使用 getter(函數):

? 1. 監聽多個響應式值組合而成的結果

watch(() => x.value + y.value, (sum) => {
console.log(‘sum changed to’, sum);
});

Vue 會追蹤 x.value 和 y.value,因為這兩個都在函數體中。

? 2. 監聽嵌套屬性(不是 ref)

const state = reactive({ a: { b: 1 } });

watch(() => state.a.b, (newVal) => {
console.log(‘b changed:’, newVal);
});

? 3. 統一寫法增強可讀性

有時你團隊約定都用 getter 函數,這樣避免有人忘了 .value 或混用 ref/reactive。

💡最佳實踐建議

情況 推薦寫法
監聽 ref 值(簡單場景) 直接寫 x
監聽多個響應式值組合 () => x.value + y.value
監聽深層屬性 / reactive 屬性 () => obj.nested.prop
想統一寫法、避免歧義 全部寫成 () => xxx.value

? 最后總結一句話:

寫成 x 是 Vue 對 ref 的“糖”,寫成 () => y.value 是通用的 getter。雖然它們監聽效果一樣,但表達方式和使用場景略有不同。

四、watch是有返回值的?

是的,watch 在 Vue 3 中 是有返回值的!

watch 返回一個 停止監聽的函數,也叫做 stop handle。

你可以在不需要監聽的時候,調用它來 手動停止這個 watch。

🧪 舉個例子:

import { ref, watch } from ‘vue’;

const count = ref(0);

const stop = watch(count, (newVal) => {
console.log(‘count changed to’, newVal);
});

// 5秒后停止監聽
setTimeout(() => {
stop(); // 👈 調用這個函數,watch 不再觸發
console.log(‘Stopped watching count’);
}, 5000);

? 常見用途:
1. 組件銷毀前手動清理監聽
(不過通常不需要,因為 Vue 會自動清理)
2. 只監聽一次某個變化后就停止

const stop = watch(count, (val) => {
if (val > 10) {
console.log(‘Too big!’);
stop(); // 👈 只監聽一次滿足條件后停止
}
});

🧠 總結:

特性 說明
返回值 是一個函數(stop handle)
作用 調用后立即停止當前的監聽器
適用場景 想主動控制監聽生命周期(如監聽一次或臨時監聽)

五、回顧一下箭頭函數
在這里插入圖片描述

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

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

相關文章

強化學習入門:價值、回報、策略概念詳解

前言 最近想開一個關于強化學習專欄,因為DeepSeek-R1很火,但本人對于LLM連門都沒入。因此,只是記錄一些類似的讀書筆記,內容不深,大多數只是一些概念的東西,數學公式也不會太多,還望讀者多多指教…

基于“數智立體化三維架構”框架的醫療數智化機制研究

1 研究背景與框架基礎 當前,全球醫療服務體系正經歷深刻的數智化轉型浪潮,人工智能、大數據、云計算等新一代信息技術與醫療健康領域的融合不斷深入,催生了醫療服務模式的革命性變化。在我國,數智化技術已成為提升基層衛生服務質量、促進醫療服務公平可及、增進百姓健康福…

OpenCV CUDA模塊圖像變形------對圖像進行旋轉操作函數rotate()

操作系統:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 編程語言:C11 算法描述 該函數用于對圖像進行 GPU 加速的旋轉操作,支持指定旋轉角度、縮放中心偏移和插值方法。是 OpenCV CUDA 模塊中用于圖像旋轉的核心函…

【面板數據】中國與世界各國新能源汽車進出口數據-分類別與不分類別(2017-2024年)

新能源汽車作為中國制造高質量發展的重要代表,其進出口數據不僅反映了我國技術實力與產業格局的變化,也是理解全球綠色交通趨勢、制定國家戰略決策的重要依據。目前國內主流定義判斷標準主要參考中國工信部于2009年發布的《新能源汽車生產企業及產品準入…

亞馬遜云服務器(AWS)會限制用戶使用嗎?深度解讀AWS資源政策

一、AWS的資源邏輯:為什么說"不限速"? AWS采用"按需分配"的資源配置模式,其核心限制并非來自人為設定,而是取決于: 實例類型配置(如t2.micro默認CPU積分制) 賬戶服務配額…

頂級視頻生成大模型分析:Seedance 1.0 Pro (字節跳動) - 新晉榜首

📖 目錄 一、概述與市場格局 1.1 AI視頻生成技術現狀1.2 主要競爭者概覽1.3 評測標準與方法 二、頂級模型詳細分析 2.1 Seedance 1.0 Pro (字節跳動) - 新晉榜首2.2 OpenAI Sora - 行業先驅者2.3 Google Veo 3 - 音視頻一體化領航者2.4 快手可靈 2.0 - 國產之光…

【Spring源碼核心篇-08】spring中配置類底層原理和源碼實現

Spring源碼核心篇整體欄目 內容鏈接地址【一】Spring的bean的生命周期https://zhenghuisheng.blog.csdn.net/article/details/143441012【二】深入理解spring的依賴注入和屬性填充https://zhenghuisheng.blog.csdn.net/article/details/143854482【三】精通spring的aop的底層原…

【無標題】在 4K 高分辨率(如 3840×2160)筆記本上運行 VMware 虛擬機時平面太小字體太小(ubuntu)

? 方法一:寫入 ~/.xprofile(推薦) 這個文件會在你登錄圖形界面前自動執行,適合設置縮放比例等桌面配置。 1. 打開 .xprofile 文件(如果沒有會自動創建): nano ~/.xprofile2. 寫入以下內容&a…

「Linux文件及目錄管理」目錄結構及顯示類命令

Linux文件系統的目錄結構 Linux文件系統采用嚴格的樹形結構,所有文件和目錄都從根目錄(/)開始延伸。以下是主要目錄的詳細說明: /bin:存放系統啟動和運行所必需的二進制可執行文件,如ls、cp、mv等基本命令。/etc:存放系統配置文件,如/etc/passwd(用戶賬戶信息)、/et…

人工智能學習13-Numpy-規律數組生成

人工智能學習概述—快手視頻 人工智能學習13-Numpy-規律數組生成—快手視頻 NumPy(Numerical Python)是 Python 的一種開源的數值計算擴展。 這種工具可用來存儲和處理大型矩陣,比 Python 自身的嵌套列表 (nested list structure…

Spring Boot 集成 Redis 實戰教程

前言 在高并發、大數據量的應用場景中,緩存是提升系統性能的關鍵技術。Redis 憑借其卓越的讀寫性能、豐富的數據結構和高可用性,成為開發者常用的緩存工具。本教程將嚴格依據Spring 官方文檔與Redis 官方文檔,詳細介紹 Spring Boot 與 Redis…

龍蜥開發者說:我的龍蜥開源之旅 | 第 32 期

「龍蜥開發者說」第 32 期來了!開發者與開源社區相輔相成,相互成就,這些個人在龍蜥社區的使用心得、實踐總結和技術成長經歷都是寶貴的,我們希望在這里讓更多人看見技術的力量。本期故事,我們邀請了龍蜥社區開發者潘玨…

在mac上安裝sh腳本文件

要將 jd-gui.sh 腳本轉換為在 macOS ARM 系統上帶有自定義圖標的可點擊運行的程序,你可以通過創建一個應用程序包(.app)來實現。以下是詳細步驟: 步驟 1:創建應用程序包目錄結構 應用程序包實際上是一個特殊的目錄&a…

用bilibili一個講座視頻,生成一本科普書籍

用bilibili一個講座視頻,生成一本科普書籍 一、功能介紹1.1 智能文本處理1.2 知識提煉與結構化1.3 專業知識普及1.4 自動化書籍生成1,5 大規模處理能力二、技術特點三、應用意義3.1 教育領域3.2 研究領域3.3 內容創作3.4 企業應用四、創新價值五、使用場景示例六、操作步驟6.1 …

黑馬教程強化day3-1

目錄 一、File1.定義:2.創建File類的對象3.File提供的判斷文件類型、獲取文件信息功能4.File提供的創建的方法5.File類刪除文件的功能6.File提供的遍歷文件夾的方法代碼演示 二、遞歸(了解遞歸算法,以便實現多級遍歷找文件)1.定義…

milvus 總結

1. milvus 的默認 admin 角色賬號 root 的密碼 為 Milvus 2. 最開始使用命令: docker-compose -f milvus-standalone-docker-compose.yml up -d 啟動 milvus 后,使用 attu 登錄 Milvus 是不需要輸入賬號/密碼的,可以使用如下方式開啟 mi…

基于docker技術的單主機環境模擬測試批量客戶端

EX. 任務背景 近期接到一個需求是在一個高性能服務器上,模擬啟動多個待測試客戶端的場景,但這個客戶端程序有點特殊,設置了守護模式,并且需要管理員權限會監控系統的/dev/mem節點,單個環境中只能啟動一個。 當前的測…

windows上用vnc viewer 能連接mac,不能連ubuntu

如果 VNC Viewer 可以連接 macOS,但無法連接 Ubuntu,通常是由于 Ubuntu 上的 VNC 服務配置問題或網絡限制導致的。以下是逐步排查和解決方案: 1. 確認 Ubuntu 上已安裝并運行 VNC 服務 (1) 檢查是否安裝了 VNC 服務器 Ubuntu 常用的 VNC 服…

Electron-vite【實戰】MD 編輯器 -- 編輯區(含工具條、自定義右鍵快捷菜單、快捷鍵編輯、拖拽打開文件等)

最終效果 頁面 src/renderer/src/App.vue <div class"editorPanel"><div class"btnBox"><divv-for"(config, key) in actionDic":key"key"class"btnItem":title"config.label"click"config.a…

沒有寶塔面板的服務器上的WordPress網站打包下載到本地?

在服務器上部署的wordpress博客站&#xff0c;沒有寶塔面板&#xff0c;怎么將服務器上的wordpress打包下載到本地&#xff1f; 作者: 曉北斗NorSnow 曉北斗動態視覺設計師&#xff0c;嵐度視覺工作室執行人&#xff1b;主要從事展廳視頻制作、圖形工作站銷售、AIGC研究&#…