Vue中watch的用法详解及与computed的区别
本文详细解析Vue中watch监听器的基本用法,包括handler、immediate和deep属性的配置与作用。深入对比watch与computed在缓存机制、异步支持及适用场景上的核心差异,并结合实例说明如何在实际开发中合理选择监听器与计算属性,优化组件性能。
一、watch是什么?
watch是Vue实例中用于监测数据变化的表达式或方法。其回调函数接收新值和旧值作为参数,通过自定义函数替代默认行为来实现监听逻辑。
简而言之,watch用于监控特定值的变换,并在值发生变化时执行相应的回调方法。它允许开发者根据数据变化动态调整关联的状态或执行副作用操作。
二、应用基本用法
当firstName的值发生变化时,watch会监听到该变化并执行对应的firstName监听函数。
<div>
<p>FullName: {{fullName}}</p>
<p>FirstName: <input type="text" v-model="firstName"></p>
</div>
new Vue({
el: '#root',
data: {
firstName: 'Kobe',
lastName: 'Bryant',
fullName: ''
},
watch: {
firstName(newName, oldName) {
this.fullName = newName + ' ' + this.lastName;
}
}
})handler方法和immediate属性:
上述示例仅在值变化时执行watch回调。若希望组件加载时立即触发回调函数,需使用handler方法和immediate属性进行配置。
watch: {
firstName: {
handler(newName, oldName) {
this.fullName = newName + ' ' + this.lastName;
},
// 代表在wacth里声明了firstName这个方法之后立即先去执行handler方法,如果设置了false,那么效果和上边例子一样
immediate: true
}
}
deep属性(深度监听,常用于对象下面属性的改变):
<div>
<p>obj.a: {{obj.a}}</p>
<p>obj.a: <input type="text" v-model="obj.a"></p>
</div>
new Vue({
el: '#root',
data: {
obj: {
a: 123
}
},
watch: {
obj: {
handler(newName, oldName) {
console.log('obj.a changed');
},
immediate: true
}
}
})
在输入框中修改数据以试图改变obj.a的值时,发现监听无效。受现代JavaScript语言限制(以及Object.observe被废弃),Vue无法直接检测对象属性的添加或删除操作。
由于Vue在初始化实例时会对属性执行getter/setter转换,因此属性必须在data对象上存在才能被Vue转换并变为响应式。
对象和数组属于引用类型,变量存储的是内存地址。若地址未变,watch不会触发。此时需开启深度监听,即设置deep属性为true。
例如,在mounted生命周期钩子函数中对obj进行重新赋值:
mounted: {
this.obj = {
a: '456'
}
}
此时deep属性发挥作用:
watch: {
obj: {
handler(newName, oldName) {
console.log('obj.a changed');
},
immediate: true,
deep: true
}
}
这种全量监听方式对性能影响较大,修改obj内任何属性都会触发handler。优化方案是将watch监听的属性指定为'obj.a',并移除deep: true配置。
watch: {
'obj.a': {
handler(newName, oldName) {
console.log('obj.a changed');
},
immediate: true,
// deep: true
}
}
最后:实际开发中,watch监听器会随组件销毁而一并移除。
在watch中避免使用箭头函数,因为箭头函数中的this指向当前作用域,而非Vue实例,可能导致无法正确访问data或methods。
三、Watch和computed的区别
计算属性computed (如果一个值依赖多个属性):
- 支持缓存机制,仅当依赖数据发生改变时才重新计算。这意味着只要lastName和firstName未变,多次访问fullName计算属性将直接返回缓存结果,无需重复执行函数。
- 不支持异步操作,当computed内部包含异步逻辑时无效,无法监听数据变化。
- computed属性值默认走缓存,基于响应式依赖进行缓存。其数据源为data中声明或父组件传递的props。
- 若某属性由其他属性计算得出,存在多对一或一对一依赖关系,通常使用computed。即使data中未直接声明计算变量,也可在computed中直接定义。
- 若computed属性值为函数,默认执行get方法,返回值即为属性值。computed中的属性同时具备get和set方法,数据变化时调用set方法。

侦听属性watch(一个值变化会引起一系列值的变化或某个数据变化时做一些事情):
- 若需在数据变化时执行异步操作或处理较大开销的任务,watch为最佳选择。
- 不支持缓存,数据一旦变化,直接触发相应操作。
- watch支持异步操作。
- 监听函数接收两个参数:第一个为最新值,第二个为变化前的旧值。
- 当一个属性变化时需执行对应操作,属于一对多关系。
- 监听数据必须是data中声明或父组件传递的props中的数据,数据变化时触发其他操作。

computed和watch的综合运用实例
需求:
1.点击按钮实现天气的切换;
2.用watch进行监视天气产生变化的数据;


实现代码(helloworld.vue实现代码)
<template>
<!-- 准备好一个容器-->
<div id="root">
<h2>今天天气很{{info}}</h2>
<button @click="changeWeather">切换天气</button>
</div>
</template>
<script>
export default {
name:'HelloWorld',
data(){
return{
isHot:true,
}
},
computed:{
info(){
return this.isHot ? '炎热' : '凉爽'
}
},
methods: {
changeWeather(){
this.isHot = !this.isHot
}
},
watch:{
isHot(val){
console.log("isHot被修改了,isHot值为:",val)
}
}
}
</script>
<style>
</style>注意:watch监听的对象都是在data()中已经定义好的数据。
以上为个人经验,希望能给大家一个参考,也希望大家多多支持本站。
怎么在 Vue 3 和 React 项目中封装使用 Quill.js 编辑器
2026-11-02 10:28:27
Vue 和 React 项目中集成 qrcode.js 的注意事项
2026-11-02 10:28:19
Vue3实现多内容滑动轮播组件完整代码示例
2026-10-31 20:20:59
Element Plus 中 mt-x 类的使用与卡片间距调整
2026-10-31 16:50:52
前端qrcode生成二维码安装及使用示例详解
2026-10-31 15:22:14
