一文带你掌握vue3中侦听器的使用

 更新时间:2023年09月05日 14:30:55   作者:哄哄  
侦听器和计算属性都可以用于侦听响应式数据的变化,如果需要在数据变化后执行操作,修改依赖项,那么就应该使用侦听器,下面就跟随小编一起来学习一下vue3中侦听器的使用吧

侦听器

侦听器和计算属性都可以用于侦听响应式数据的变化,如果需要在数据变化后执行操作,修改依赖项,那么就应该使用侦听器
watchwatchEffect都可以侦听数据源并执行回调操作,不同的是他们追踪响应式依赖的方式。

watch:只追踪指定的数据源,所以可以精确地控制回调函数的触发时机

watchEffect:自动追踪回调内的响应式数据,相比watch更加简洁,但有时其响应性依赖关系会不那么明确。

watch函数

第一个参数需要指定需要侦听的数据。

可以是响应式数据(ref、reactive、computed...)、getter函数、也可以是以上数据源组成的数组,也就是同时侦听多个数据源。

第二个参数是在侦听到数据变动时,需要执行的回调方法。

该回调方法有两个参数,第一个为数据更新后的值,第二个为数据更新前的值。

import { ref, watch } from 'vue'
const count = ref(0)
const price = ref(10)
// 侦听响应式数据
watch(count, (newVal, oldVal) => {
    // 每当count更新时,都会执行这里的函数
    console.log("new count:", newVal) // 1  更新后的值
    console.log("old count:", oldVal) // 0  更新前的值
})
// 侦听getter函数
watch(
    () => count.value * price.value,
    (newVal, oldVal) => {
        // 每当count或者price更新时,都会执行这里的函数
        console.log("新总价:", newVal) // 10  更新后的值
        console.log("旧总价:", oldVal) // 0  更新前的值
    })
// 使用数组侦听多个数据源
watch(
    [count, () => price.value],
    (newValArr, oldValArr) => {
        // 每当count或者price更新时,都会执行这里的函数
        // 需要注意此时的回调数据为数组
        // newValArr[0] count
        // newValArr[1] () => price.value]
        // oldValArr 同上
        console.log(newValArr) // [1, 10]  更新后的值
        console.log(oldValArr) // [0, 10]  更新前的值
    })
count.value++ // 更新count值

可选配置

以上两个参数在侦听器中是必传的,除此之外watch函数还有一些可选配置。

立即执行

watch默认是在数据源更新时才会执行回调,如果想要在创建时立刻执行回调函数,就可以通过传入 immediate:true 使侦听器的回调立即执行

const count = ref(0)
watch(count, (newVal,oldVal) => {
    console.log(newVal)  // 0
    console.log(oldVal)  // undefind
}, {
    immediate: true  // 创建时立即执行一次回调
})

深层侦听器

给watch函数传入一个响应式对象,会隐式地创建一个深层侦听器——该回调函数在所有嵌套的变更时都会被触发:

const obj1 = reactive({ val: 1 })
watch(obj1, (newVal, oldVal) => {
    // 在obj的嵌套属性变更时触发
    // 注意此处的newVal oldVal的值是相等的
    // 因为他们是同一个对象
})
const obj2 = ref({ val: 2 })
// 传入ref侦听的对象时,添加.value才会默认创建深层侦听
watch(obj2.value, (newVal, oldVal) => {})
obj1.val++
obj2.value.val++

当直接传入ref创建的对象或是返回响应式对象的getter函数时,只有在它们的对象被整个替换时才会触发回调。如果也想创建深层侦听,可以通过传入deep:true强制转成深层侦听器。

// 当直接传入ref创建的对象或是返回响应式对象的getter函数时
// 只有在它们的对象被整个替换时才会触发回调
//  例:obj2.value = { val: 3 }
// 传入deep选项即可创建深层侦听
// getter函数
watch(() => obj2.value, (newVal, oldVal) => {
    // 注意此处的newVal oldVal的值是相等的
    // 除非替换掉整个obj2.value
}, {
    deep: true   // 当值变更时触发回调
})
// ref创建的对象数据
watch(obj2, (newVal, oldVal) => {
    // 注意此处的newVal oldVal的值是相等的
    // 除非替换掉整个obj2.value
}, {
    deep: true   // 当值变更时触发回调
})

watchEffect函数

和计算属性一样,不需要指定要侦听的响应式数据,而是会自动跟踪回调的响应式依赖,并在依赖变化时重新执行回调函数;

并且创建后回调会立即执行一次(不需要传入 immediate:true);

相比watch函数更加简洁方便。

import { ref, watchEffect } from 'vue';
const count = ref(0)
watchEffect(() => {
    console.log(count.value) // 0
})

停止侦听

当业务需要,或者在异步操作中创建侦听器时,

可以通过以下方法来停止侦听器。

const unwatch = watchEffect(() => { })
// 当不需要时调用 unwatch() 即可销毁侦听
unwatch()
setTimeout(() => {
  // 在同步中创建的侦听器在组件销毁时,自动停止,而异步中创建的不会!
  watchEffect(() => {})
}, 100)

DOM更新后触发回调

侦听的数据源变更,有可能同时触发vue组件更新与侦听器回调。

默认情况下,回调会在组件更新之前执行,也就是在回调中获取dom获取到的是vue组件更新之前的状态,

如果想要在回调中访问更新之后的状态那么就需要传入flush: 'post'选项

watch(count, ()=>{
}, {
  flush: 'post'
})
watchEffect(()=>{
}, {
  flush: 'post'
})

注意点

watch函数的回调参数

回调函数的参数有两个,第一个为"新值",第二个为"旧值",如果只需要使用"新值",可以忽略第二个值,

如果监听的数据是对象,那么他们的"新值"与"旧值"是相等的,因为都指向同一个内存地址,除非整个替换掉。

尽量不要在异步中创建侦听

尽量不要在异步中创建侦听,在异步中创建的侦听不会自动销毁,如果在异步中创建侦听,请手动结束侦听。

到此这篇关于一文带你掌握vue3中侦听器的使用的文章就介绍到这了,更多相关vue3侦听器内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • vue.js计算属性computed用法实例分析

    vue.js计算属性computed用法实例分析

    这篇文章主要介绍了vue.js计算属性computed用法,结合实例形式分析了vue.js使用computed方式进行属性计算的相关操作技巧,需要的朋友可以参考下
    2018-07-07
  • VUE3+Element-plus中el-form的使用示例代码

    VUE3+Element-plus中el-form的使用示例代码

    这篇文章主要介绍了VUE3+Element-plus中el-form的使用示例代码,本文通过图文示例代码相结合给大家介绍的非常详细,需要的朋友可以参考下
    2024-07-07
  • vue3中使用props和emits并指定其类型与默认值

    vue3中使用props和emits并指定其类型与默认值

    props是Vue3中的一个重要概念,它允许我们将数据从父组件传递到子组件,下面这篇文章主要给大家介绍了关于vue3中使用props和emits并指定其类型与默认值的相关资料,需要的朋友可以参考下
    2023-04-04
  • vue使用router-view调用页面方式

    vue使用router-view调用页面方式

    这篇文章主要介绍了vue使用router-view调用页面方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-03-03
  • vue的列表交错过渡实现代码示例

    vue的列表交错过渡实现代码示例

    这篇文章主要介绍了vue的列表交错过渡实现代码示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-05-05
  • vue组件发布到npm简单步骤

    vue组件发布到npm简单步骤

    给大家讲解一下vue组件发布到npm简单方法和步骤过程,需要的朋友一起学习参考一下。
    2017-11-11
  • 详解如何在vue项目中引入elementUI组件

    详解如何在vue项目中引入elementUI组件

    这篇文章主要介绍了详解如何在vue项目中引入elementUI组件,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-02-02
  • vue实现评论列表

    vue实现评论列表

    这篇文章主要为大家详细介绍了vue实现评论列表,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-04-04
  • Vue3实现预览PDF文件的多种方式(超简单)

    Vue3实现预览PDF文件的多种方式(超简单)

    在Vue项目中实现PDF文件预览是许多开发者可能会遇到的需求,尤其是在开发海外后台管理系统时,由于某些用户上传的文件格式为PDF,而Vue本身并不直接支持PDF文件的预览功能,这就需要借助一些第三方的插件或者工具来完成,下面详细地介绍几种在Vue3中实现PDF文件预览的方法
    2025-03-03
  • vue业务实例之组件递归及其应用

    vue业务实例之组件递归及其应用

    目中出现多级菜单时,需要多层for循环时,但是当菜单增加层级时,需要在页面结构中增加一层for循环,这时我们可以使用组件递归的思想来实现,下面这篇文章主要给大家介绍了关于vue业务实例之组件递归及其应用的相关资料,需要的朋友可以参考下
    2022-05-05

最新评论