必须使用 Getter 函数,因为 Vue 响应式系统依赖依赖收集,只有在副作用执行中被读取的响应式属性才会被追踪;直接传字符串或解构值无法建立响应联系,而 () => obj.prop 能在 watch 执行时触发依赖记录,实现精准监听。

Vue 3 中想监听响应式对象里的某个属性(比如 user.name 或 form.items[0].status),不能直接传字符串路径(如 "user.name"),也不能只传对象本身(否则会监听整个对象的引用变化)。正确做法是使用 Getter 函数 —— 即一个返回目标属性值的函数,让 watch 能够“追踪”它的依赖。
为什么必须用 Getter 函数?
Vue 的响应式系统基于依赖收集:只有在副作用执行过程中被读取的响应式属性,才会被自动追踪。直接传 obj.prop 是取值操作,不是“可追踪的访问”;而传一个函数(如 () => obj.prop),watch 在首次执行时会调用它,期间读取到的响应式属性就会被记录为依赖。后续该属性变化时,watch 才能精准触发。
基础写法:监听单个嵌套属性
假设你有如下响应式对象:
从零开始编排 SpringBoot+Vue 全栈项目工作流,适用于新建全栈项目或完整脚手架请求,触发后依次调用 product‑spec‑builder(需求调研)等模块。
const state = reactive({
user: {
name: 'Alice',
age: 28
}
})
监听 state.user.name 的变化,这样写:
watch(
() => state.user.name, // ✅ Getter 函数:返回要监听的值
(newVal, oldVal) => {
console.log('name changed:', oldVal, '→', newVal)
}
)
监听多个属性或动态路径
- 监听多个字段?用数组包裹多个 Getter:
watch(
[
() => state.user.name,
() => state.user.age,
() => state.settings.theme
],
([newName, newAge, newTheme], [oldName, oldAge, oldTheme]) => {
// 每个参数按顺序对应数组中的 getter
}
)
- 监听数组某项?同样用函数访问:
const list = reactive([{ id: 1, done: false }])
watch(
() => list[0]?.done, // ✅ 支持可选链,避免报错
(done) => {
console.log('first item done:', done)
}
)
注意事项和常见坑
-
不要解构后再监听:❌
const { name } = state.user; watch(() => name, ...)—— 这会丢失响应性,因为name是普通字符串,不是响应式引用。 -
深层监听对象所有属性?用
deep: true,但注意性能开销;仅监听特定字段时,优先用 Getter,更精准、更高效。 - Getter 中避免副作用或复杂逻辑:watch 会多次调用它(初始化、依赖更新时),应保持纯函数特性(只读、无修改、无异步)。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!









