watch 是 Vue 响应式核心特性,专门监听数据变化并执行回调,主打处理异步操作、复杂逻辑,和 computed 互补,是开发必备技能。本文极简梳理核心用法,Vue2/Vue3 全覆盖,易懂好上手。
一、watch 能干嘛?
- 监听data/计算属性/响应式数据的变更
- 数据变了自动执行回调,做后续操作(调接口、改状态、DOM 操作等)
- 适合:异步请求、多数据联动、初始化执行逻辑、监听对象 / 数组内部变化
二、Vue2 选项式 API:watch 基础用法
1. 基础监听:简单数据类型
针对简单数据类型,直接以"数据名"作为 watch 的键,值为回调函数,回调接收两个核心参数:newVal(数据变化后的值)、oldVal(数据变化前的值)。
javascript
new Vue({
data: { msg: 'Vue2', count: 0 },
watch: {
// 监听msg,newVal新值,oldVal旧值
msg(newVal, oldVal) {
console.log('msg变了');
},
// 结合业务逻辑
count(newVal) {
if (newVal > 5) alert('count超过5了');
}
}
})
2. 深度监听:对象 / 数组内部变化
默认 watch 是浅监听,只监引用地址变化,对象内部属性改了不触发,需加deep: true,回调写在handler里。
javascript
new Vue({
el: '#app',
data: {
user: { name: '张三', age: 20 }, // 引用数据:对象
list: [1, 2, 3] // 引用数据:数组
},
watch: {
// 深度监听user对象,其内部任意属性变化均会触发回调
user: {
handler(newVal) {
console.log('user内部属性变更:', newVal);
},
deep: true // 关键:开启深度监听
},
// 同理,深度监听数组内部元素变化
list: {
handler(newVal) {
console.log('数组元素变更:', newVal);
},
deep: true
}
}
})
3. 立即执行:页面初始化就触发
watch 默认是"惰性执行",仅在数据第一次变更后才触发回调,页面初始化、组件创建时不执行。若需页面加载时立即执行一次回调(如初始化时根据默认值调用接口),需配置 immediate: true。
javascript
watch: {
user: {
handler(newVal) { console.log('user内部变了:', newVal); },
immediate:true
}
}
三、Vue3 组合式 API:watch 函数
Vue3 用
前置:Vue3 响应式数据
1. 基础监听:ref/reactive 数据
语法:watch(监听目标, 回调函数, 配置项)
2. 精准监听:reactive 对象单个属性
监听 reactive 对象的某个属性,用箭头函数返回属性,避免监听整个对象浪费性能。
javascript
watch(() => user.age, (newVal) => { console.log('年龄变了:', newVal); });
watch(() => user.address.city, (newVal) => { console.log('城市变了:', newVal); });
四、watch 与 computed区分
很多开发者会混淆 watch 与 computed,二者均能处理数据联动,但设计初衷、适用场景完全不同,核心区分如下,记住后再也不混用。
watch
- 数据变化后执行,无返回值
- 支持异步操作
- 处理复杂业务逻辑、多数据联动
computed
- 依赖数据变化前计算,必须有返回值
- 仅支持同步操作
- 处理简单数据派生
核心选型建议:能用 computed 解决的问题,优先用 computed(更简洁、性能更优);需要处理异步、复杂逻辑时,再用 watch。
五、watch 使用避坑指南
- 避免过度使用深度监听:深度监听(deep: true)会递归遍历引用数据的所有属性,层级越深,性能开销越大
- 禁止在 watch 回调中修改被监听数据:会触发无限循环(数据变化→回调执行→修改数据→再次触发回调)
- 初始化逻辑优先用 immediate: true:无需在 mounted 中重复编写与 watch 相同的逻辑,减少代码冗余
总结
- watch 核心:监听数据变化,执行回调,主打异步和复杂逻辑;
- Vue2 是配置项,需 deep/immediate,监听属性用字符串路径;
- Vue3 是导入函数,reactive 自动深度,监听单个属性用箭头函数,多数据监听传数组;
- 和 computed 互补:异步用 watch,同步用 computed;