Vue3中computed和watch的區別

文章目錄

  • 前言
    • 🔍 一、`computed` vs `watch`
      • ? 示例對比
        • 1. `computed` 示例(適合模板綁定、衍生數據)
        • 2. `watch` 示例(副作用,如調用接口)
    • 🧠 二、源碼實現原理(簡化理解)
      • 1. `computed` 原理
      • 2. `watch` 原理
    • 📌 三、使用建議
    • 擴展:
    • 🧠 四、Vue 3 響應式系統核心:`effect` / `track` / `trigger`
      • 1. `effect(fn)`:響應式副作用收集器
      • 2. `track(target, key)`:依賴追蹤
      • 3. `trigger(target, key)`:依賴觸發
      • 🔁 總結:響應式機制流程
    • 🔁 五、`watchEffect` 是什么?
      • 🌟 特點:
      • 📦 內部工作機制(簡化版)
    • 🧪 應用場景對比
    • ? 實戰案例:watch vs watchEffect
      • `watch` 示例(明確監聽)
      • `watchEffect` 示例(更簡潔)


前言

Vue 3 中 computedwatch區別源碼實現邏輯(Composition API 版本)。


🔍 一、computed vs watch

項目computedwatch
類型派生狀態(緩存)響應式副作用
用途根據已有響應式變量派生出新數據監聽某個響應式數據的變化后執行副作用邏輯
是否緩存? 是? 否
返回值Ref(值類型)void(返回值無意義)
使用場景顯示用、模板綁定API 調用、定時器、調試、數據同步等

? 示例對比

1. computed 示例(適合模板綁定、衍生數據)
const price = ref(100)
const tax = ref(0.1)const total = computed(() => price.value * (1 + tax.value))
// total.value = 110
2. watch 示例(副作用,如調用接口)
watch(price, (newVal, oldVal) => {console.log(`價格變化:${oldVal} -> ${newVal}`)// 比如向服務器匯報價格變動
})

🧠 二、源碼實現原理(簡化理解)

1. computed 原理

  • Vue 內部使用了 effectRef 實現 computed
  • 默認是 lazy effect,只有在訪問 .value 時才執行計算。
  • Vue 自動追蹤依賴(依賴收集),只在依賴變化時重新執行。
function computed(getter) {const result = ref()const runner = effect(getter, {lazy: true,scheduler: () => {dirty = true}})return {get value() {if (dirty) {result.value = runner()dirty = false}return result.value}}
}

關鍵點:緩存 + 懶執行 + 自動依賴追蹤


2. watch 原理

  • watch 是對 effect 的進一步封裝。
  • 內部會遞歸地跟蹤傳入的響應式數據,建立響應關系。
  • 依賴變動時,會執行用戶提供的回調函數。
function watch(source, cb) {let oldValue = source()effect(() => {const newValue = source()if (newValue !== oldValue) {cb(newValue, oldValue)oldValue = newValue}})
}

關鍵點:不緩存 + 只執行副作用 + 深層依賴可配置


📌 三、使用建議

需求推薦
只用來展示(派生數據)computed
需要執行副作用(發請求、console.log、同步)watch
復雜對象監聽watch 配合 deep: true
多個數據合并監聽watch([a, b])

擴展:

  • watchEffect 的解釋
  • 或深入理解 Vue 的響應式核心 effecttracktrigger 機制

繼續深入講解 Vue 3 響應式系統的核心:effecttracktrigger,并說明 watchEffect 是如何工作的。


🧠 四、Vue 3 響應式系統核心:effect / track / trigger

1. effect(fn):響應式副作用收集器

  • 用于包裹副作用函數(如 computed 的 getter 或 watch 的監聽函數)。
  • 在函數中讀取響應式數據時,會被自動“追蹤依賴”。
effect(() => {console.log(state.count)  // 依賴 `state.count`
})

2. track(target, key):依賴追蹤

  • 當你讀取響應式對象的屬性時,會觸發 track
  • track 會記錄當前活躍的 effect,讓這個 effect 依賴這個屬性。
// 簡化版
function track(target, key) {if (!activeEffect) returnlet depsMap = targetMap.get(target)if (!depsMap) {depsMap = new Map()targetMap.set(target, depsMap)}let deps = depsMap.get(key)if (!deps) {deps = new Set()depsMap.set(key, deps)}deps.add(activeEffect)
}

3. trigger(target, key):依賴觸發

  • 當你修改響應式數據時,會觸發 trigger
  • 它會找到依賴這個屬性的所有 effect,然后重新執行它們。
function trigger(target, key) {const depsMap = targetMap.get(target)if (!depsMap) returnconst effects = depsMap.get(key)effects.forEach(effect => effect())
}

🔁 總結:響應式機制流程

  1. effect(fn) 執行時讀取響應式數據 → track 收集依賴
  2. 數據變化時 → trigger 調用依賴的 effect → 重新執行

🔁 五、watchEffect 是什么?

🌟 特點:

  • 類似 computed,但用于副作用。
  • 自動收集依賴,無需顯式聲明。
  • 依賴變更時自動重新執行副作用函數。
watchEffect(() => {console.log(`count 是 ${count.value}`)
})

📦 內部工作機制(簡化版)

function watchEffect(effectFn) {const runner = effect(effectFn)return () => stop(runner)
}
  • watchEffect 調用時立即執行 effectFn
  • 響應式依賴被收集。
  • 當依賴變更時,會重新調用 effectFn
  • 返回的函數可用于停止監聽。

🧪 應用場景對比

需求場景推薦工具
計算派生值computed
副作用 + 明確監聽字段watch
副作用 + 自動依賴收集watchEffect

? 實戰案例:watch vs watchEffect

watch 示例(明確監聽)

watch(() => user.id, (newId) => {fetchUserDetail(newId)
})

watchEffect 示例(更簡潔)

watchEffect(() => {fetchUserDetail(user.id)
})

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

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

相關文章

C++修煉:C++11(二)

Hello大家好&#xff01;很高興我們又見面啦&#xff01;給生活添點passion&#xff0c;開始今天的編程之路&#xff01; 我的博客&#xff1a;<但凡. 我的專欄&#xff1a;《編程之路》、《數據結構與算法之美》、《題海拾貝》、《C修煉之路》 歡迎點贊&#xff0c;關注&am…

單元測試與QTestLib框架使用

一.單元測試的意義 在軟件開發中&#xff0c;單元測試是指對軟件中最小可測試單元&#xff08;通常是函數、類的方法&#xff09;進行隔離的、可重復的驗證。進行單元測試具有以下重要意義&#xff1a; 1.提升代碼質量與可靠性&#xff1a; 早期錯誤檢測&#xff1a; 在開發…

(附實現代碼)Step-Back 回答回退策略擴大檢索范圍

1. LangChain 少量示例提示模板 在與 LLM 的對話中&#xff0c;提供少量的示例被稱為 少量示例&#xff0c;這是一種簡單但強大的指導生成的方式&#xff0c;在某些情況下可以顯著提高模型性能&#xff08;與之對應的是零樣本&#xff09;&#xff0c;少量示例可以降低 Prompt…

16-Oracle 23 ai-JSON-Relational Duality-知識準備

一直做DBA的小伙伴&#xff0c;是不是對開發相對陌生一些。JSON 關系二元性是 Oracle Database 23ai 中重要的特性&#xff0c;同時帶來的是范式革命。JSON關系二元性解決了數據庫領域的根本矛盾?&#xff0c;結構化數據的嚴謹性與半結構化數據的靈活性之間的矛盾。 JSON Rela…

什么是預訓練?深入解讀大模型AI的“高考集訓”

1. 預訓練的通俗理解&#xff1a;AI的“高考集訓” 我們可以將預訓練&#xff08;Pre-training&#xff09; 形象地理解為大模型AI的“高考集訓”。就像學霸在高考前需要刷五年高考三年模擬一樣&#xff0c;大模型在正式誕生前&#xff0c;也要經歷一場聲勢浩大的“題海戰術”…

思爾芯攜手Andes晶心科技,加速先進RISC-V 芯片開發

在RISC-V生態快速發展和應用場景不斷拓展的背景下&#xff0c;芯片設計正面臨前所未有的復雜度挑戰。近日&#xff0c;RISC-V處理器核領先廠商Andes晶心科技與思爾芯&#xff08;S2C&#xff09;達成重要合作&#xff0c;其雙核單集群AX45MPV處理器已在思爾芯最新一代原型驗證系…

vscode配置lua

官網下載lua得到如下 打開vscode的擴展下載如下三個 打開vscode的此處設置 搜索 executorMap&#xff0c;并添加如下內容

理解 RAG_HYBRID_BM25_WEIGHT:打造更智能的混合檢索增強生成系統

目錄 理解 RAG_HYBRID_BM25_WEIGHT&#xff1a;打造更智能的混合檢索增強生成系統 一、什么是 Hybrid RAG&#xff1f; 二、什么是 RAG_HYBRID_BM25_WEIGHT&#xff1f; 三、參數設置示例 四、什么時候該調整它&#xff1f; 五、實戰建議 六、總結 理解 RAG_HYBRID_BM25…

Spring Boot 2 中 default-autowire 的使用

Spring Boot 2 中 default-autowire 的使用 在 Spring Boot 2 中&#xff0c;default-autowire 這個來自傳統 XML 配置的概念仍然存在&#xff0c;但它的使用已經大大減少&#xff0c;因為現代 Spring Boot 應用主要使用注解驅動的配置方式。 default-autowire 在 Spring Boo…

Spring Boot + Thymeleaf 防重復提交

在 Spring Boot 與 Thymeleaf 結合的 Web 應用中&#xff0c;防止重復提交可以采用token 機制 客戶端禁用按鈕的方式實現&#xff0c;在高并發場景下&#xff0c;考慮使用 Redis 存儲 token 而非 Session。 第一步&#xff1a;后端實現 Controller public class FormControl…

【20250607接單】Spark + Scala + IntelliJ 項目的開發環境配置從零教學

本教程適用于零基礎、一臺剛裝好 Windows 的全新電腦開始&#xff0c;搭建能運行 Spark Scala IntelliJ 項目的開發環境。以下是超詳細、小白級別逐步教程&#xff0c;從“下載什么”到“點擊哪里”都幫你列清楚。 &#x1f3af; 目標 操作系統&#xff1a;Windows10/11工具…

【ubuntu】虛擬機安裝配置,sh腳本自動化,包含 apt+時間同步+docker+mysql+redis+pgsql

可以說是ubuntu基礎環境搭建合集&#xff0c;個人學習用&#xff0c;使用sh一鍵安裝&#xff0c;避免復制各種命令 流程主要包括 0. 可選擇不同ubuntu版本對應安裝&#xff08;支持 Ubuntu 20.04/22.04/23.04/24.04&#xff09; 1. apt換源aliyun 2. 時間選擇上海時區&#x…

Rust 學習筆記:關于智能指針的練習題

Rust 學習筆記&#xff1a;關于智能指針的練習題 Rust 學習筆記&#xff1a;關于智能指針的練習題問題一問題二問題三問題四問題五問題六問題七問題八問題九問題十問題十一 Rust 學習筆記&#xff1a;關于智能指針的練習題 參考視頻&#xff1a; https://www.bilibili.com/vi…

JavaScript ES6 解構:優雅提取數據的藝術

JavaScript ES6 解構&#xff1a;優雅提取數據的藝術 在 JavaScript 的世界中&#xff0c;ES6&#xff08;ECMAScript 2015&#xff09;的推出為開發者帶來了許多革命性的特性&#xff0c;其中“解構賦值”&#xff08;Destructuring Assignment&#xff09;無疑是最受歡迎的功…

Shell 命令及運行原理 + 權限的概念(7)

文章目錄 Shell 命令以及運行原理&#xff08;4-1.22.08&#xff09;Linux權限的概念1. 什么是權限2. 認識人&#xff08;普通用戶&#xff0c;root用戶&#xff09;以及兩種用戶的切換認識普通用戶和root用戶兩種用戶之間的切換指令提權 3. 文件的屬性解析 權限屬性指令ll顯示…

以智能管理為基礎,樓宇自控打造建筑碳中和新路徑

在全球氣候變化的嚴峻形勢下&#xff0c;“碳中和”已成為各國發展的重要戰略目標。建筑行業作為能源消耗與碳排放的“大戶”&#xff0c;其運行階段的能耗占全社會總能耗近40%&#xff0c;碳排放占比與之相當&#xff0c;實現建筑碳中和迫在眉睫。傳統建筑管理模式下&#xff…

Python爬蟲實戰:研究Hyper 相關技術

一、項目概述 本項目展示了如何結合 Python 的異步編程技術與 Hyper 框架開發一個高性能、可擴展的網絡爬蟲系統。該系統不僅能夠高效地爬取網頁內容,還提供了 RESTful API 接口,方便用戶通過 API 控制爬蟲的運行狀態和獲取爬取結果。 二、系統架構設計 1. 整體架構 系統采…

html 滾動條滾動過快會留下邊框線

滾動條滾動過快時&#xff0c;會留下邊框線 但其實大部分時候是這樣的&#xff0c;沒有多出邊框線的 滾動條滾動過快時留下邊框線的問題通常與滾動條樣式和滾動行為有關。這種問題可能出現在使用了自定義滾動條樣式的情況下。 注意&#xff1a;使用方法 6 好使&#xff0c;其它…

【Linux】Ubuntu 創建應用圖標的方式匯總,deb/appimage/通用方法

Ubuntu 創建應用圖標的方式匯總&#xff0c;deb/appimage/通用方法 對于標準的 Ubuntu&#xff08;使用 GNOME 桌面&#xff09;&#xff0c;desktop 后綴的桌面圖標文件主要保存在以下三個路徑&#xff1a; 當前用戶的桌面目錄&#xff08;這是最常見的位置&#xff09;。所…

【自然語言處理】大模型時代的數據標注(主動學習)

文章目錄 A 論文出處B 背景B.1 背景介紹B.2 問題提出B.3 創新點 C 模型結構D 實驗設計E 個人總結 A 論文出處 論文題目&#xff1a;FreeAL: Towards Human-Free Active Learning in the Era of Large Language Models發表情況&#xff1a;2023-EMNLP作者單位&#xff1a;浙江大…