在 Vue.js 2 中,watch 是一个用于监听数据变化并执行自定义逻辑的核心功能。它特别适合处理异步操作或复杂的数据响应场景。以下是 watch 的详细解析:
1. 基本用法
在 Vue 实例的 watch 选项中定义监听器,监听特定的数据属性:
new Vue({
data() {
return {
message: 'Hello',
user: { name: 'Alice', age: 25 }
};
},
computed: {
// 定义一个计算属性返回要监听的属性值
userAge() {
return this.user.age;
}
},
watch: {
// 监听 message 的变化
message(newVal, oldVal) {
console.log(`新值: ${newVal}, 旧值: ${oldVal}`);
},
// 监听嵌套对象属性
'user.name'(newVal) {
console.log(`用户名变更为: ${newVal}`);
}
// 借助计算属性间接监听:灵活性更高
userAge(newVal, oldVal) {
console.log(`新的年龄: ${newVal}, 旧的年龄: ${oldVal}`);
}
}
});
2. 配置选项
通过对象语法配置 handler、deep(深度监听)、immediate(立即触发)、sync(回调是否同步执行):
watch: {
user: {
handler(newVal, oldVal) {
console.log('user 对象变化', newVal);
},
deep: true, // 深度监听对象内部变化
immediate: true, // 初始化时立即执行一次 handler
sync: false // 回调在DOM更新后触发,默认行为
}
}
deep: true
监听对象或数组内部的变化(如嵌套属性修改)。immediate: true
在组件初始化时立即触发一次回调。sync: true
回调立即触发,DOM尚未更新
3. 监听动态路径
使用字符串路径监听嵌套属性:
watch: {
'user.address.city': {
handler(newVal) {
console.log('城市变更:', newVal);
}
}
}
4. 监听计算属性
watch 也能对计算属性进行监听,当计算属性的值改变时,会触发相应的回调函数。
export default {
data() {
return {
firstName: '',
lastName: ''
};
},
computed: {
fullName() {
return `${this.firstName} ${this.lastName}`;
}
},
watch: {
fullName(newVal, oldVal) {
console.log(`新的全名: ${newVal}, 旧的全名: ${oldVal}`);
}
}
};
5. 动态监听与取消监听
通过 vm.$watch 动态添加监听器,并可手动取消:
const vm = new Vue({ /* ... */ });
// 动态监听
const unwatch = vm.$watch('message', (newVal) => {
console.log('动态监听:', newVal);
});
// 取消监听
unwatch();
6. 与 computed 的对比
computed
适合派生数据(基于依赖缓存,自动更新)。watch
适合数据变化时的副作用操作(如异步请求、复杂逻辑)。
7. 注意事项
- 性能问题
避免对大型对象使用deep: true,可能引发性能损耗。 - 数组监听
Vue 2 无法直接监听数组索引变化,需用Vue.set或数组变异方法(如push)。 - 避免循环更新
在监听回调中修改其他数据时,确保不会导致无限循环。
8. 示例场景
- 搜索框防抖
监听输入值,延迟触发搜索请求。 - 表单验证
监听表单字段变化,实时校验数据。 - 路由参数响应
监听路由参数变化,重新加载数据。
总结
Vue 2 的 watch 提供了灵活的数据监听机制,结合 deep 和 immediate 可应对复杂场景。合理使用 watch 和 computed 能让代码更高效清晰。在 Vue 3 中,watch 的功能通过 Composition API 进一步增强,但 Vue 2 的语法仍是经典模式的核心工具。