Vue3中的watch与watchEffect的使用与区别#记录

本文详细解释了Vue.js中的watch和watchEffect函数,包括它们的参数、工作原理、适用场景,以及何时选择watch或watchEffect来监听数据变化和DOM更新。特别强调了深度监听、旧值处理以及flush选项的作用。
摘要由CSDN通过智能技术生成

一、watch

watch() 默认是懒侦听的,即仅在侦听源发生变化时才执行回调函数。

watch 有三个参数:

1、第一个参数是需要侦听的数据

(1)一个 ref 或者一个响应式对象

(2)一个函数,返回一个值

(3)由以上类型的值组成的数组

2、第二个参数是数据发生变化时的回调

第二个参数是在发生变化时要调用的回调函数。 这个回调函数接受三个参数:新值、旧值,以及一个用于注册副作用清理的回调函数。 该回调函数会在副作用下一次重新执行前调用,可以用来清除无效的副作用,例如等待中的异步请求。

//当侦听多个来源时,回调函数接受两个数组,分别对应来源数组中的新值和旧值。

watch([aRef, bRef], ([newA, newB], [prevA, prevB]) => {
  /* ... */
})

3、第三个参数是一个可选的对象

  • immediate:在侦听器创建时立即触发回调。第一次调用时旧值是 undefined。
  • deep:如果源是对象,强制深度遍历,以便在深层级变更时触发回调。
  • flush:回调函数的刷新时机。
  • onTrack / onTrigger:调试侦听器的依赖。
flush
  • pre (默认)
    侦听器将在组件渲染之前执行。
  • post
    将会使侦听器延迟到组件渲染之后再执行。
  • sync
    响应式依赖发生改变时立即触发侦听器。
onTrack / onTrigger

onTrack 依赖项被追踪时被调用,只会执行一次。 onTrigger 依赖项变更导致副作用被触发时被调用。只在开发模式下生效。

 注意事项

1、当侦听一个响应式对象时,侦听器会自动启用深层模式。
const state = reactive({ count: 0 })
watch(state, () => {
  /* 深层级变更状态所触发的回调 */
})
2、watch 只能监听响应式数据:ref 定义的属性和 reactive 定义的对象,如果直接监听 reactive 定义对象中的属性是不允许,只能使用函数转换一下,就是官网说的监听一个 getter。
const state = reactive({ count: 0 })
watch(
  () => state.count,
  (count, prevCount) => {
    /* ... */
  },
  {
    deep: true
  }
)
3、侦听 一个 ref
const count = ref(0)
watch(count, (count, prevCount) => {
  /* ... */
})

二、watchEffect()

立即运行一个函数,同时响应式地追踪其依赖,并在依赖更改时重新执行

watchEffect 有两个参数

1、第一个参数是数据发生变化时执行的回调函数。

watchEffect(() => {
    //监听state.str
    console.log(state.str)

    // 会在 props 变化时打印
    console.log(a, b, c)
  })

2、第二个参数是一个可选的对象,支持 flush 和 onTrack / onTrigger 选项,功能和 watch 相同。

watchEffect(() => {}, {
  flush: 'post',
  onTrack(e) {
    debugger
  },
  onTrigger(e) {
    debugger
  }
})

注意

1、watchEffect 不支持深度监听,如果监听 reactive 定义的对象是不起作用的,只能监听对象中的属性。
2、3.2 版本以上可以用 watchPostEffect watchSyncEffect 代替 flush: 'post' flush: 'sync'。
3、watchEffect 动态加入的依赖不会被清除。
4、watchEffect,则会在副作用发生期间追踪依赖。它会在同步执行过程中,自动追踪所有能访问到的响应式属性。

三、什么时候应该使用 watch 和 watchEffect

  • 如果需要依赖旧值必须使用 watch。
  • 需要深度监听时必须使用 watch。
  • watchEffect 侦听数据变化写法比较简单,但是不能轻易的操作依赖值,否则会重复触发。
  • 如果回调函数不依赖侦听值那么需要用 watch。
  • 需要明确知道由哪个状态触发的则必须用 watch。

 四、访问 Vue 更新之后的 DOM

在 Vue2.x 中, 使用 nextTick, 在Vue3 中,watch / watchEffect 指明 flush: 'post' 选项 即可。

//watch
watch(source, callback, {
  flush: 'post'
})

//watchEffect
watchEffect(callback, {
  flush: 'post'
})

//watchEffect也可以使用watchPostEffect 
import { watchPostEffect } from 'vue'

watchPostEffect(() => {
  /* 在 Vue 更新后执行 */
})

  • 51
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值