Vue3中ref数组的监听实现方式

 更新时间:2025年10月28日 11:00:12   作者:BillKu  
Vue3中监听ref定义的数组,需根据监听需求选择合适的监听方法,对于空数组,推荐使用深度监听来捕捉数组内部变化,同时,确保修改数组的方式是响应式的,以保证监听器能正常工作,根据具体需求,可以选择直接深度监听、监听数组长度变化或提取属性监听等方案

在Vue 3中,监听一个由 ref 定义的数组【特别是像你这样初始化为空数组的情况 const jjdData = ref<JJD[]>([])】,关键在于理解你希望监听何种类型的变化。

下面用一个表格汇总主要的监听场景和方法,方便你快速了解:

监听场景推荐写法说明
数组被整体替换watch(jjdData, (newVal) => { ... })监听整个数组的引用变化。
数组内部变化(增删元素)及元素自身变化watch(jjdData, (newVal) => { ... }, { deep: true })最常用。深度监听,可响应数组方法和元素属性的变化。
仅监听数组长度的变化watch(() => jjdData.value.length, (newLen) => { ... })只关心元素数量的增减,不关心具体内容变化。
监听数组中特定对象属性的变化watch(() => jjdData.value.map(item => item.someProperty), (newVals) => { ... })例如,只关心每个 JJD 对象的 id 或 name 属性是否变化。

监听器的详细写法与注意事项

1.基本监听与深度监听

对于你的 jjdData,如果它最初是空数组,然后在组件挂载后被赋值(例如通过异步请求),你需要使用深度监听来捕捉数组本身以及其内部对象元素的变化。

import { watch } from 'vue';

// 深度监听,可以响应数组替换、数组方法调用以及对象元素属性的变化
watch(
  jjdData,
  (newArray, oldArray) => {
    console.log('数组发生了变化', newArray);
    // 在这里执行你的副作用逻辑
  },
  { deep: true } // 关键配置
);

注意

当监听 reactive 定义的响应式数据时,会强制开启深度监视,但对于 ref 定义的数组,需要显式配置 deep: true

使用 deep: true 时,oldArray 可能与 newArray 相同,因为它们指向同一个响应式代理对象。

2.提取属性进行监听

如果只想监听数组内对象某些特定属性的集合变化,可以使用计算属性提取后再监听,这有助于减少不必要的回调。

import { watch, computed } from 'vue';

// 提取出所有需要监听的属性,组成一个新数组
const somePropertyList = computed(() => jjdData.value.map(item => item.someProperty));

watch(somePropertyList, (newValues, oldValues) => {
  // 比较 newValues 和 oldValues 来确定具体哪个索引的属性发生了变化
  console.log('某个对象的someProperty发生了变化', newValues);
});
// 或者使用getter函数
watch(
  () => jjdData.value.map(item => item.someProperty),
  (newVals, oldVals) => { ... }
);

3.动态管理监听器(适用于大型动态数组)

对于频繁增删元素的大型数组,如果需要为每个元素的特定属性建立单独的监听器,可以考虑动态管理监听器,但通常复杂度较高。

import { watch, onScopeDispose } from 'vue';

const stops = new Map(); // 用来存储每个监听器的停止函数

// 监听整个数组的变化,以管理针对每个元素的监听器
watch(
  () => [...jjdData.value],
  (newArr, oldArr) => {
    // 逻辑:对比新老数组,为新增元素创建监听器,为删除的元素移除监听器
    // ... (具体实现可参考搜索结果中的示例:cite[2])
  },
  { deep: true }
);

// 组件卸载时清理所有监听器
onScopeDispose(() => {
  stops.forEach(stop => stop());
  stops.clear();
});

除非有非常精确的需求,否则更推荐使用前面提到的深度监听或提取属性监听的方法。

确保响应式变化的注意事项

为了让监听正常生效,你需要确保修改数组的方式是响应式的:

  • 变更数组本身:推荐使用数组的变更方法,如 pushpopspliceshiftunshift 等,或者直接对整个数组进行赋值(例如 jjdData.value = newArray)。
  • 修改数组内的对象元素:直接通过索引修改对象属性(例如 jjdData.value[0].name = 'new value')在Vue 3的响应式系统下是可以被 deep: true 检测到的。但更推荐的做法是创建一个新对象进行替换,以保证变化的可追踪性,例如 jjdData.value[0] = { ...jjdData.value[0], name: 'new value' }

如何选择监听方案

  • 对于大多数情况,直接使用 deep: true 进行深度监听是最简单直接的选择。
  • 如果只关心数组是否被整体替换,或者只关心数组长度的变化,可以使用非深度监听。
  • 如果数组很大,或者只关心里面对象的某一个特定属性,使用提取属性并监听的方式性能会更优。
  • 尽量避免在大型动态数组上为每个元素单独创建监听器,除非确有必要,因为管理起来比较复杂。

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • vue项目中解决 IOS + H5 滑动边界橡皮筋弹性效果(解决思路)

    vue项目中解决 IOS + H5 滑动边界橡皮筋弹性效果(解决思路)

    最近遇到一个问题,我们在企业微信中的 H5 项目中需要用到table表格(支持懒加载 上划加载数据),但是他们在锁头、锁列的情况下,依旧会出现边界橡皮筋效果,这篇文章主要介绍了vue项目中解决 IOS + H5 滑动边界橡皮筋弹性效果,需要的朋友可以参考下
    2023-02-02
  • Vue双向数据绑定(MVVM)的原理

    Vue双向数据绑定(MVVM)的原理

    这篇文章主要介绍了Vue双向数据绑定的原理,帮助大家更好的理解和学习vue,感兴趣的朋友可以了解下
    2020-10-10
  • vue中如何去掉input前后的空格

    vue中如何去掉input前后的空格

    这篇文章主要介绍了vue中如何去掉input前后的空格问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-03-03
  • 在Vue3中实现四种全局状态数据的统一管理的方法

    在Vue3中实现四种全局状态数据的统一管理的方法

    在开发中,通常遇到四种全局状态数据:异步数据、同步数据,传统的Vue3使用不同机制处理这些数据,而Zova框架通过Model机制来统一管理,简化了数据处理流程,提高了代码的可维护性,本文介绍在Vue3中实现四种全局状态数据的统一管理的方法,感兴趣的朋友一起看看吧
    2024-10-10
  • vue使用路由的query配置项时清除地址栏的参数案例详解

    vue使用路由的query配置项时清除地址栏的参数案例详解

    这篇文章主要介绍了vue使用路由的query配置项时如何清除地址栏的参数,本文通过案例给大家分享完美解决方案,需要的朋友可以参考下
    2023-09-09
  • vite打包出现"default" is not exported by "node_modules/...问题解决

    vite打包出现"default" is not exported by "no

    这篇文章主要给大家介绍了关于vite打包出现"default" is not exported by "node_modules/...问题解决的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2023-11-11
  • vue中使用axios的作用

    vue中使用axios的作用

    Axios是一个功能强大、易用性高的HTTP库,适用于大多数的前端项目,它提供了丰富的功能和灵活的配置选项,可以满足不同项目的需求,这篇文章主要介绍了vue中使用axios的作用,需要的朋友可以参考下
    2023-08-08
  • Vue过滤器与内置指令和自定义指令及组件使用详解

    Vue过滤器与内置指令和自定义指令及组件使用详解

    这篇文章主要介绍了Vue过滤器与内置指令和自定义指令及组件使用方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习吧
    2022-12-12
  • vueJS简单的点击显示与隐藏的效果【实现代码】

    vueJS简单的点击显示与隐藏的效果【实现代码】

    下面小编就为大家带来一篇vueJS简单的点击显示与隐藏的效果【实现代码】。小编觉得挺不错的,现在分享给大家,一起跟随小编过来看看吧
    2016-05-05
  • Vue3新特性Composition API实战指南

    Vue3新特性Composition API实战指南

    Vue3的发布标志着这个流行前端框架的重大升级,其中最引人注目的变化是引入了Composition API,本文将深入探讨Vue3的新特性,特别是Composition API的实际应用,帮助开发者掌握这一强大工具,需要的朋友可以参考下
    2025-07-07

最新评论