当前位置: 首页 > news >正文

Vue 3 中 watch 的使用与深入理解

在 Vue 3 的 Composition API 中,watch 是一个非常强大的工具,用于监听响应式数据的变化并做出相应的处理。本文将通过一段实际代码来深入解析 watch 的行为和使用技巧。


🧩 示例代码回顾

import { reactive, watch } from 'vue'const state = reactive({a: 1,b: 2,c: 3
})watch(() => {console.log(state.a + state.b)return state.a + state.b},(val) => {console.log(val * 2)}
)setTimeout(() => {state.a++//state.bstate.b--
}, 1000)

🔍 初识 watch

基本结构

Vue 的 watch 函数接收三个参数:

  1. source(监听源):可以是一个响应式引用(如 ref)、一个返回值的 getter 函数、或一个包含多个源的数组。
  2. callback(回调函数):当 source 变化时执行的函数。
  3. options(可选配置):例如 { immediate: true, deep: true }

本例中的逻辑

  • 我们定义了一个响应式对象 state,包含属性 abc
  • 使用 watch 监听 state.a + state.b 的变化,并在变化时打印其两倍值。
  • 在 1 秒后修改ab 的值。

⚙️ 深入分析

1. 初始化阶段

当组件加载时,watch 的第一个函数会被立即调用:

() => {console.log(state.a + state.b) // 输出 3return state.a + state.b
}

此时 a = 1, b = 2,所以 a + b = 3,控制台输出 3

由于这是第一次运行,还没有发生任何变化,因此不会触发回调 (val) => console.log(val * 2)


2. 修改状态后的行为

1 秒后,执行以下操作:

state.a++ // a = 2
state.b-- // b = 1

此时 a + b = 3,与之前的值相同。

虽然 ab 都发生了变化,但它们的和没有改变,因此 watch 回调 (val) => console.log(val * 2) 不会被触发

但是,下面这行代码仍然会执行:

console.log(state.a + state.b) // 输出 3

这是因为每次依赖项发生变化时,getter 函数都会重新执行一次以检查是否有变化。


📌 控制台输出顺序

  1. 页面加载时:3(来自watch函数体内 console.log
  2. 1 秒后:
    -3(来自watch函数体再次执行)
    • 不会输出 6,因为 a + b 的值没有改变

🧪 如何让watch强制触发?

如果你希望即使值不变也触发回调,可以考虑以下方式:

✅ 使用 immediate: true

watch(() => {console.log(state.a + state.b)return state.a + state.b},(val) => {console.log(val * 2)},{ immediate: true }
)

这样你会看到两次 3和一次 6(在 setTimeout 后)。

注意:deep: true 对基础类型无效,通常用于对象或数组。


💡 实际应用场景

watch 常用于以下场景:

  • 表单验证:监听输入框内容变化
  • 数据同步:当某个值变化时更新其他状态
  • 异步请求:根据用户输入发起搜索请求
  • 路由守卫:监听路由变化并执行相应逻辑

🧠 小结

知识点内容
watch初始执行会执行一次 getter 函数,但不会触发回调
触发回调条件必须是返回值发生变化才会触发
控制台输出即使不触发回调,getter 函数也会重新执行
强制首次触发可使用 { immediate: true }

📚 总结

Vue 3 的watch 提供了灵活的数据监听机制,但它的行为有时可能会让人困惑。理解它的工作原理,尤其是如何判断“变化”,对于编写高效且可维护的响应式逻辑至关重要。

通过上面的例子,我们不仅掌握了watch的基本用法,还了解了它的内部机制以及如何控制其行为。希望这篇文章能帮助你更好地理解和使用 Vue 3 的响应式系统!

http://www.xdnf.cn/news/459649.html

相关文章:

  • SpringBoot集成Redis:实现分布式锁(redistemplate,lua,redisson)
  • 《深入理解AXI4协议:从入门到实践》-- 第十篇:AXI5与CHI协议前瞻
  • 人工神经网络(ANN)模型
  • 【微服务】SpringBoot + Docker 实现微服务容器多节点负载均衡详解
  • GPUGeek云平台实战:DeepSeek-R1-70B大语言模型一站式部署
  • 计算机网络:蜂窝网络和WiFi网络使用的射频信号有什么区别?
  • 【视频】解决FFmpeg将RTSP转RTMP流时,出现的卡死、出错等问题
  • 安全巡检清单
  • Linux云计算训练营笔记day08(MySQL数据库)
  • 硅基计划2.0 学习总结 贰
  • SQL:MySQL函数:空值处理函数(NULL Handling Functions)
  • 阿克曼-幻宇机器人系列教程3- 机器人交互实践(Message)
  • React和Vue在前端开发中, 通常选择哪一个
  • 机器学习 day03
  • stm32使用freertos时延时时间间隔不对,可能是晶振频率没设置
  • CF每日5题(1300-1500)
  • 提高成功率!课题中的立项依据深度写作
  • Python中plotext 库详细使用(命令行界面中直接绘制各种图形)
  • [IMX] 03.时钟树 - Clock Tree
  • 力扣310.最小高度树(拓扑排序,无向图),力扣.加油站力扣.矩阵置零​​​力扣.二叉树中的最大路径和
  • AI数字人:技术革新与应用全景解析
  • Linux中安装samba服务
  • (C语言)超市管理系统 (正式版)(指针)(数据结构)(清屏操作)(文件读写)
  • CVPR-2022《Efficient Deep Embedded Subspace Clustering》
  • 机器学习 --- 模型选择与调优
  • java17
  • 【Pandas】pandas DataFrame diff
  • 【Linux】gcc从源码编译安装,修改源码,验证修改的源码
  • 数据科学和机器学习的“看家兵器”——pandas模块 之三
  • undefined reference to CPUAllocatorSingleton::instance