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

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