vue3 监听器,组合式API的watch用法

2024-06-08 02:44

本文主要是介绍vue3 监听器,组合式API的watch用法,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

watch函数

在组合式 API 中,我们可以使用 watch 函数在每次响应式状态发生变化时触发回调函数

watch(ref,callback(newValue,oldValue),option:{})
ref:被监听的响应式量,可以是一个 ref (包括计算属性)、一个响应式对象、一个 getter 函数、或多个数据源组成的数组
callback:回调函数,当被监听的响应式量变化是触发回调,callback有两个参数,类型和ref一致,值是捕获到的变化后的ref,和变化前的ref
option: 对象提供一些监听函数的监听参数,比如是否开启深层监听

一个最简单的监听示例

<script setup>
import { ref, watch } from 'vue'const count = ref(0);watch(count, () => {console.log(count.value);
})</script><template><div><span>{{ count }}</span></div><button @click="count++">click</button>
</template>

当按钮点击时count递增,watch函数会捕获count的变化,并触发回调函数打印出count的值

这里 点击了20下每次变化都触发了一次回调

监听getter

<script setup>
import { ref,reactive, watch } from 'vue'const count = ref(0);
const obj = reactive({num:0});watch(count, (num) => {console.log("count=",num);
})watch(()=> obj.num , (num) => {console.log("sum=",num);
})</script><template><div><span>sum=</span><span>{{ count }}+</span><span>{{ obj.num }}</span></div><button @click="count++,obj.num++">click</button>
</template>

这里不能直接监听响应式对象的值(obj.sum ),而是需要用一个返回该属性的 getter 函数要监听的值( ()=> obj.sum ) 

深层监听器

深层侦听需要遍历被侦听对象中的所有嵌套的属性,对于一个对象来说,没有深度监听只有当整个对象改变才会被捕获,

虽然不能直接监听响应式对象的值,但是可以直接监听响应式对象,这会隐式的激活深层监听

  <div><span>sum=</span><span>{{ count }}+</span><span>{{ obj.num }}</span></div><button @click="count++,obj.num++">click</button>

const obj = reactive({num:0});watch( obj, (newValue,oldValue)=>{console.log(newValue,oldValue);
})

可以看出来回调的两个对象参数它们式相等的两个值,

当你监听对象内嵌套的对象时,则需要手动开启深层监听,否则只有当整个对象改变时才能被捕获

<div><span>sum=</span><span>{{ count }}+</span><span>{{ obj.num }}</span>
</div>
<button @click="count++,obj.num++,ob.obj.num++">click</button>
<span>嵌套对象的属性{{ ob.obj.num }}</span>
const ob = ref({obj:{num:0,str:"hello"},count:0
})watch(()=>ob.value.obj, (newValue,oldValue)=>{console.log(newValue,oldValue);
},{deep:true
})

 可以看到开启深层监听后就可以捕获到变化响应了

立刻回调和一次回调

{deep:true,immediate:true,once:true
}

除了深层回调还有两个参数,immediate,once,布尔值,它们分别表示,立刻执行一次回调(在开始捕获之前)和只回调一次(只捕获一次响应变化)

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>

这篇关于vue3 监听器,组合式API的watch用法的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1041010

相关文章

vue解决子组件样式覆盖问题scoped deep

《vue解决子组件样式覆盖问题scopeddeep》文章主要介绍了在Vue项目中处理全局样式和局部样式的方法,包括使用scoped属性和深度选择器(/deep/)来覆盖子组件的样式,作者建议所有组件... 目录前言scoped分析deep分析使用总结所有组件必须加scoped父组件覆盖子组件使用deep前言

VUE动态绑定class类的三种常用方式及适用场景详解

《VUE动态绑定class类的三种常用方式及适用场景详解》文章介绍了在实际开发中动态绑定class的三种常见情况及其解决方案,包括根据不同的返回值渲染不同的class样式、给模块添加基础样式以及根据设... 目录前言1.动态选择class样式(对象添加:情景一)2.动态添加一个class样式(字符串添加:情

使用SpringBoot创建一个RESTful API的详细步骤

《使用SpringBoot创建一个RESTfulAPI的详细步骤》使用Java的SpringBoot创建RESTfulAPI可以满足多种开发场景,它提供了快速开发、易于配置、可扩展、可维护的优点,尤... 目录一、创建 Spring Boot 项目二、创建控制器类(Controller Class)三、运行

oracle中exists和not exists用法举例详解

《oracle中exists和notexists用法举例详解》:本文主要介绍oracle中exists和notexists用法的相关资料,EXISTS用于检测子查询是否返回任何行,而NOTE... 目录基本概念:举例语法pub_name总结 exists (sql 返回结果集为真)not exists (s

React实现原生APP切换效果

《React实现原生APP切换效果》最近需要使用Hybrid的方式开发一个APP,交互和原生APP相似并且需要IM通信,本文给大家介绍了使用React实现原生APP切换效果,文中通过代码示例讲解的非常... 目录背景需求概览技术栈实现步骤根据 react-router-dom 文档配置好路由添加过渡动画使用

Springboot中Jackson用法详解

《Springboot中Jackson用法详解》Springboot自带默认json解析Jackson,可以在不引入其他json解析包情况下,解析json字段,下面我们就来聊聊Springboot中J... 目录前言Jackson用法将对象解析为json字符串将json解析为对象将json文件转换为json

使用Vue.js报错:ReferenceError: “Vue is not defined“ 的原因与解决方案

《使用Vue.js报错:ReferenceError:“Vueisnotdefined“的原因与解决方案》在前端开发中,ReferenceError:Vueisnotdefined是一个常见... 目录一、错误描述二、错误成因分析三、解决方案1. 检查 vue.js 的引入方式2. 验证 npm 安装3.

vue如何监听对象或者数组某个属性的变化详解

《vue如何监听对象或者数组某个属性的变化详解》这篇文章主要给大家介绍了关于vue如何监听对象或者数组某个属性的变化,在Vue.js中可以通过watch监听属性变化并动态修改其他属性的值,watch通... 目录前言用watch监听深度监听使用计算属性watch和计算属性的区别在vue 3中使用watchE

python解析HTML并提取span标签中的文本

《python解析HTML并提取span标签中的文本》在网页开发和数据抓取过程中,我们经常需要从HTML页面中提取信息,尤其是span元素中的文本,span标签是一个行内元素,通常用于包装一小段文本或... 目录一、安装相关依赖二、html 页面结构三、使用 BeautifulSoup javascript

Vue3 的 shallowRef 和 shallowReactive:优化性能

大家对 Vue3 的 ref 和 reactive 都很熟悉,那么对 shallowRef 和 shallowReactive 是否了解呢? 在编程和数据结构中,“shallow”(浅层)通常指对数据结构的最外层进行操作,而不递归地处理其内部或嵌套的数据。这种处理方式关注的是数据结构的第一层属性或元素,而忽略更深层次的嵌套内容。 1. 浅层与深层的对比 1.1 浅层(Shallow) 定义