【Vue3】监听器watch的使用

文章详细解释了Vue3中如何使用watch和watchEffect进行数据监听,包括ref和reactive数据的处理方式、深度监听、停止监听以及watchEffect的性能特点。
摘要由CSDN通过智能技术生成

定义

监听器:监视某个或某些数据,当其变化时,作出相应处理。

可监视数据

  1. ref数据 注意:监听时不需要写 .value
  2. reactive数据
  3. getter函数,「返回一个值的函数」
  4. 以上所有数据的集合 「数组」

语法

注意: 当value为ref数据时,不同于其他地方使用,不需要加.value。

watch(value,(newValue,oldValue)=>{...处理函数},{deep:true,......})

参数说明

  1. 监听的数据
  2. 回调函数,第一个参数为newValue,即修改后的当前值;第二个参数为oldValue,即修改前的值
  3. 配置对象,常用如:deep,immediate…

使用

情况一:如何停止监听

watch函数的返回值是一个「stop函数」,在处理函数中调用「stop函数」即可。

在这里插入图片描述

情况二:监听ref的基本数据

watch的第一个参数不需要写 .value

watch(value,(newValue,oldValue)=>{...处理函数},{deep:true,......})

情况三:监听ref的对象数据

如果直接监听对象,默认只有对象被替换成新对象时才会触发,如 obj.value={a:1}。
属性值改变(obj的址未发生改变)则不会监听到。

若要监听每个属性值的变化,则需要开启深度监视,watch函数第三个参数(配置对象)中,添加deep:true。
watch(obj,()=>{},{deep:true})

若对象的值发生改变,则watch的第二个参数中,newValue和oldValue为一对象
若对象的址发生改变,则watch的第二个参数中,newValue和oldValue为不同对象

情况四:监听reactive数据

如果监听的是reactive数据,默认开启深度监听,且不可关闭,每个属性值改变都会触发。

情况五:监听ref或reactive对象中的某个属性

如果这个属性不是四种可监视数据之一,例如;就是一个基本类型,则报错,需要改为getter函数(一个函数返回一个值)的写法。
在这里插入图片描述

如果监听的是对象中的对象,例如car,watch(person.car,()=>{}),因为监听的是对象,所以可以不写成函数,只有属性值发生变化时,才会被监听,如果整个对象被替换,如下图,则无法触发。
在这里插入图片描述
如果想要监听整个car对象,需要写成函数式,但一定要开启深度监听,否则只有整个对象被替换才会触发。
在这里插入图片描述
总结: 如果监听的是对象中的某个属性,推荐写函数返回值的形式。如果这个属性是对象数据,则可以不写成函数,但是址改变(对象替换)无法被监听。

情况六:监听多个数据

如果监听的是多个数据,可以将他们放到一个数组中,其中一个数据发生改变就会触发处理函数。
在这里插入图片描述

情况七:当需要监听的数据过多

如果监听的数据特别多或需要监听全部响应式数据时,那么「情况六」传入数组的写法过于繁琐,wacthEffect会更加适用。

watchEffect在页面加载完毕后,默认执行一次,有点像watch加了immediate。它默认会监听所有的响应式数据,只要其中一个数据发生变化,就会触发其回调函数。

以下示例中假设有4个响应式数据,需要监听他们并做出处理。
4个数据假设为: let a = ref(1), let b = ref(2), let c = ref(3), let d = ref(4)

watch写法

import { watch } from "vue"

watch([a,b,c,d],(value)=>{
	let [a,b,c,d] = value
	if(a === 1 && b >= 2){
		......
	}
})

watchEffect写法

import { watchEffect } from "vue"

watchEffect(()=>{
	if(a.value === 1 && b.value >= 2){
		......
	}
})

注意

  • watchEffect中监听ref数据时,要加 .value
  • watchEffect虽然使用起来方便,但是与监听单个数据或指定数据相比,性能较差

总结

  • watch函数默认返回一个stop函数,可以在回调函数中调用改stop函数,停止监听。
  • watch函数监听数据为ref类型数据时,不需要写.value。因为Vue 3 在内部已经对 ref 类型做了透明化处理,使其在访问时自动解包为其内部的原始值。所以,在使用 watch 监听 ref 类型数据时,Vue 3 会自动处理解包过程,无需手动使用 .value。
  • watch函数监听数据为reactive类型数据时,默认开启深度监听不可关闭
  • 如果监听的数据为对象中的某个属性时,第一个参数需要getter函数(一个函数返回一个值)。
  • 如果需要监听多个数据,watch函数第一个参数传数组,元素为需要监听的数据。
  • 如果监听的数据很多,或者需要监听所有数据时,使用watchEffect
  • watchEffect 是一个响应式函数,它接受一个函数作为参数。当函数内部引用的任何响应式数据发生变化时,该函数都会被重新执行。此外,该函数会在页面初始渲染后自调用一次
  • watchEffect的回调函数中,使用ref数据,需要解包 .value
  • 非必要情况下,尽可能使用watch,因为其性能优于watchEffect。
Vue3中,监听器的用法发生了一些变化。Vue2中使用的`$watch`方法已经被废弃,取而代之的是`watch`函数。下面是监听器的基本用法: ```javascript import { watch } from 'vue'; const state = { count: 0, }; watch( () => state.count, // 监听的数据 (newValue, oldValue) => { // 数据改变时执行的回调函数 console.log(`count 从 ${oldValue} 变成了 ${newValue}`); } ); ``` 在上面的例子中,我们使用了`watch`函数来监听`state.count`变量的变化。当`count`发生变化时,我们会在控制台上输出变化前后的值。 我们还可以使用`immediate`选项来立即执行回调函数: ```javascript watch( () => state.count, (newValue, oldValue) => { console.log(`count 从 ${oldValue} 变成了 ${newValue}`); }, { immediate: true } ); ``` `watch`函数的第三个参数可以是一个选项对象,用来设置监听器的一些选项。除了`immediate`之外,还有`deep`、`flush`等选项可供使用。 ```javascript watch( () => state.obj, (newValue, oldValue) => { console.log('obj 变化了'); }, { deep: true, // 是否深度监听对象的变化 flush: 'sync', // 在什么时候执行回调函数,可选值:'pre'、'post'、'sync' } ); ``` 除了使用`watch`函数之外,我们还可以在模板中使用`watch`指令来监听数据的变化。 ```html <template> <div> <p>{{ count }}</p> <button @click="increment">+</button> </div> </template> <script> import { ref } from 'vue'; export default { setup() { const count = ref(0); function increment() { count.value++; } return { count, increment, }; }, watch: { count(newValue, oldValue) { console.log(`count 从 ${oldValue} 变成了 ${newValue}`); }, }, }; </script> ``` 在上面的例子中,我们在组件的`watch`选项中定义了一个监听器,用来监听`count`变量的变化。当`count`发生变化时,我们会在控制台上输出变化前后的值。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

田本初

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值