vue3 监听器,组合式API的watch用法-watchEffect函数

watchEffect会自动监听能访问到的且发生了响应变化的值,并且只跟踪回调中被使用到的属性,而不是递归地跟踪所有的属性,这有时候比深层监听遍历所有属性要更好,但是要注意,它仅会在其同步执行期间,才b捕获响应变化。在使用异步回调时,只有在第一个 await 正常工作前访问到的属性才会被捕获。

watchEffect(callback(newValue,oldValue),option:{})
callback:回调函数,当被监听的响应式量变化是触发回调,callback有两个参数,类型和ref一致,值是捕获到的变化后的ref,和变化前的ref
option: 对象提供一些监听函数的监听参数,

watch 和 watchEffect

watch 和 watchEffect 都能响应式地执行能响应的回调(触发页面变化)。它们之间的主要区别是追踪响应式依赖的方式:

watch:需要提供监听目标,监听属性更加精确,仅在监听的目标变化时触发

watchEffect: 不需要提供监听补码,监听时没有那么明确,自动追踪所有能访问到的(参与回调的)响应式属性。

<div :style="`background-color:${color}`">
  <span>sum=</span>
  <span>{{ count }}+</span>
  <span>{{ obj.num }}</span>
</div>
<button @click="count++,obj.num++,ob.obj.num++">click</button>
<button @click="color='green'">change</button>
<span>嵌套对象的属性{{ ob.obj.num }}</span>
watchEffect((newValue,oldValue)=>{
  console.log("捕获到了变化",count.value,"\n",newValue,oldValue);
  color.value = "red";
})

 回调中有count,当count变化时直接被捕获,改变了背景颜色,同时它还默认响应了一个函数

 回调触发时机

watchEffect(callback,option:{})

option:
    flush:post/sync (指明post,则会在响应后回调,指明sync,则会在响应前回调)

// 或者你可以用对应的函数;

watchPostEffect()
watchSyncEffect()

// 它们的效果是一样的

如果想在侦听器回调中能访问被 Vue 更新之后的所属组件的 DOM,你需要指明 flush: 'post' 或者使用 watchPostEffect()

如果想在侦听器回调在 Vue 进行任何更新之前触发:你需要指明 flush: 'sync' 或者使用 watchSyncEffect()

停止监听

在 setup() 或 <script setup> 中,绝大部分的监听器会随着组件销毁而结束。

关键点是,监听器必须用同步语句创建,如果用异步回调创建一个监听器,那么它不会绑定到当前组件上,你必须手动停止它,以防内存泄漏。

手动停止一个侦听器,可以调用 watch 或 watchEffect 返回的函数

const unwatch = watchEffect(() => {})

// ...当该侦听器不再需要时
unwatch()

执行这个返回的函数就可以结束监听,释放内存

代码总结

<script setup>
import { ref,reactive, watch,watchEffect } from 'vue'

const count = ref(0);
const obj = reactive({num:0});
const color = ref("");
const ob = ref({
  obj:{
    num:0,
    str:"hello"
  },
  count:0
})

watch(count, (num) => {
  console.log("count=",num);
})

watch(()=> obj.num , (num) => {
  console.log("sum=",num);
})

watch( obj, (newValue,oldValue)=>{
  console.log(newValue,oldValue);
})

watch(()=>ob.value.obj, (newValue,oldValue)=>{
  console.log(newValue,oldValue);
},{
  deep:true,
  // immediate:true,
  // once:true
})

watchEffect((newValue,oldValue)=>{
  console.log("捕获到了变化",count.value,"\n",newValue,oldValue);
  color.value = "red";
})
</script>

<template>
  <div :style="`background-color:${color}`">
    <span>sum=</span>
    <span>{{ count }}+</span>
    <span>{{ obj.num }}</span>
    
  </div>
  <button @click="count++,obj.num++,ob.obj.num++">click</button>
  <button @click="color='green'">change</button>
  <span>嵌套对象的属性{{ ob.obj.num }}</span>
</template>

上一篇:Python爬虫实战:从入门到精通


下一篇:spring boot中常用的多线程案例