前言🌟
本文诣在帮大家彻底梳理Vue3
中watch
的用法。
首先,介绍Vue3
的watch
API的基本使用,然后介绍了watch
在侦听单个数据源、多个数据源的注意事项,最后通过对比得出watch侦听引用类型数据源
的最佳实践。
一、API介绍
1 | watch(WatcherSource, Callback, [WatchOptions]) |
参数说明:
WatcherSource: 用于指定要侦听的响应式数据源。侦听器数据源可以是返回值的 getter
函数,也可以直接是 ref
。
Callback: 执行的回调函数,可依次接收当前值newValue,先前值oldValue作为入参。
WatchOptions:deep
、immediate
、flush
可选。
- 当需要对响应式对象进行深度监听时,设置
deep: true
。 - 默认情况下watch是惰性的,当我们设置
immediate: true
时,watch会在初始化时立即执行回调函数。flush
选项可以更好地控制回调的时间。它可设置为pre
、post
或sync
。- 默认值是
pre
,指定的回调应该在渲染前被调用。 post
值是可以用来将回调推迟到渲染之后的。如果回调需要通过$refs
访问更新的 DOM 或子组件,那么则使用该值。- 如果
flush
被设置为sync
,一旦值发生了变化,回调将被同步调用(少用,影响性能)。
二、侦听单个数据源及停止侦听
1 | <script setup> |
现象:配置了immediate:true
的watch
,在初始化时触发了一次watch
的回调。我们连续点击增加年龄,当年龄的当前值大于18时,watch停止了侦听。
结论:侦听器数据源可以是返回值的 getter
函数,也可以直接是 ref
。我们可以利用给watch
函数取名字
,然后通过执行名字()
函数来停止侦听。
三、监听多个数据源
1 | <script setup> |
现象:以上,当我们在同一个函数里同时改变name
和age
两个侦听源,watch
的回调函数只触发了一次;当我们在name
和age
的改变之间增加了一个nextTick
,watch
回调函数触发了两次。
结论:我们可以通过watch侦听多个数据源的变化。如果在同一个函数里同时改变这些被侦听的来源,侦听器只会执行一次。若要使侦听器执行多次,我们可以利用 nextTick
,等待侦听器在下一步改变之前运行。
四、侦听引用对象(数组Array或对象Object)
1 | <template> |
现象:当将引用对象采用ref
形式定义时,如果不加上deep:true
,watch
是侦听不到值的变化的;而加上deep:true
,watch
可以侦听到数据的变化,但是当前值和先前值一样,即不能获取先前值。当将引用对象采用reactive
形式定义时,不作任何处理,watch
可以侦听到数据的变化,但是当前值和先前值一样。两种定义下,把watch
的数据源写成getter函数的形式并进行深拷贝返回,可以在watch
回调中同时获得当前值和先前值。
结论:
当我们使用watch
侦听引用对象时
- 若使用
ref
定义的引用对象:- 只要获取当前值,watch第一个参数直接写成数据源,另外需要加上
deep:true
选项 - 若要获取当前值和先前值,需要把数据源写成getter函数的形式,并且需对数据源进行深拷贝
- 只要获取当前值,watch第一个参数直接写成数据源,另外需要加上
- 若使用
reactive
定义的引用对象:- 只要获取当前值,watch第一个参数直接写成数据源,可以不加
deep:true
选项 - 若要获取当前值和先前值,需要把数据源写成getter函数的形式,并且需对数据源进行深拷贝
- 只要获取当前值,watch第一个参数直接写成数据源,可以不加
🎉🎉🎉🎉🎉