定义
监听器:监视某个或某些数据,当其变化时,作出相应处理。
可监视数据
- ref数据
注意
:监听时不需要写 .value - reactive数据
- getter函数,「返回一个值的函数」
- 以上所有数据的集合 「数组」
语法
注意: 当value为ref数据时,不同于其他地方使用,不需要加.value。
watch(value,(newValue,oldValue)=>{...处理函数},{deep:true,......})
参数说明
- 监听的数据
- 回调函数,第一个参数为newValue,即修改后的当前值;第二个参数为oldValue,即修改前的值
- 配置对象,常用如: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。