watchEffect

4 篇文章 0 订阅

看这个名字就会发现这个配置项跟watch脱离不了关系。确实他更像进阶版的watch。
watchEffect
立即运行一个函数,同时响应式地追踪其依赖,并在依赖更改时重新执行。

let obj = reactive({name: 'fufu'})

watchEffect(() => {
	let name = obj.name
	console.log('监听到了')
})

首先会发现在最开始便打印出 ‘监听到了’,这说明watchEffect会在最开始便进行一次调用,就像普通watch的immediate属性,然后我们改变obj.name属性会发现再次打印出 ‘监听到了’,这表示watchEffect可以监听到使用过的响应数据(会自动进行深度监听)。
副作用清除
试想一下,如果里面有一个请求的方法,当这个方法还没来得及响应,有数据就已经更新并重新执行了这块的方法,那么又会重复的调用请求,这不但会浪费服务资源,甚至会造成竞态问题,所以我们需要有一个时机,这个时机允许我们在下一次调用函数之前去做一个清除的操作。

在watchEffect的第一个参数函数里面(我们叫做函数A),函数A也有一个参数,这个参数也是一个函数(我们叫他函数B),函数B的执行时机就是在下次函数A执行之前。

watchEffect(async (onCleanup) => {
  const { response, cancel } = doAsyncWork(id.value)
  // `cancel` 会在 `id` 更改时调用
  // 以便取消之前未完成的请求
  onCleanup(cancel)
  data.value = await response
})

watch的第一个参数函数里面的第三个参数也是如此

回调的触发时机
当你更改了响应式状态,它可能会同时触发 Vue 组件更新和侦听器回调。
默认情况下,用户创建的侦听器回调,都会在 Vue 组件更新之前被调用。这意味着你在侦听器回调中访问的 DOM 将是被 Vue 更新之前的状态。

如果想在侦听器回调中能访问被 Vue 更新之后的 DOM,你需要指明 flush: ‘post’

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

后置刷新的 watchEffect() 有个更方便的别名 watchPostEffect()

watch的第三二个参数对象里面也有同样配置项

停止侦听器
在平时使用时,同步语句创建的侦听器,会自动绑定到宿主组件实例上,并且会在宿主组件卸载时自动停止。因此,在大多数情况下,你无需关心怎么停止一个侦听器。
一个关键点是,侦听器必须用同步语句创建:如果用异步回调创建一个侦听器,那么它不会绑定到当前组件上,你必须手动停止它,以防内存泄漏。

<script setup>
import { watchEffect } from 'vue'

// 它会自动停止
watchEffect(() => {})

// ...这个则不会!
const unwatch = setTimeout(() => {
  watchEffect(() => {})
}, 100)
//...当该侦听器不再需要时手动停止
unwatch()
</script>

watch和watchEffect
既然已经有了watch属性,那么为什么还需要watchEffect呢?明白两者用途后就可以发现watch既需要监视的属性,也需要监视的回调函数,而watchEffect是用到哪个数据就监视哪个数据。

computed和watchEffect
有人会拿watchEffect跟computed进行比较,因为都是开始就会执行,都是依赖的值改变就会执行。但是computed注重的是返回值(函数的返回值),watchEffect注重的是过程(函数的函数体)。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值