Vue中watch的用法详解及与computed的区别

作者:模板散步

时间:2026-10-25

浏览:330

本文详细解析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为最佳选择。
  • 不支持缓存,数据一旦变化,直接触发相应操作。
  • watch支持异步操作。
  • 监听函数接收两个参数:第一个为最新值,第二个为变化前的旧值。
  • 当一个属性变化时需执行对应操作,属于一对多关系。
  • 监听数据必须是data中声明或父组件传递的props中的数据,数据变化时触发其他操作。

一、watch是什么?

computed和watch的综合运用实例

需求:

1.点击按钮实现天气的切换;

2.用watch进行监视天气产生变化的数据;

一、watch是什么?

一、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()中已经定义好的数据。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持本站。

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章