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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈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;浙江大…