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路由事件beforeRouteLeave及组件内定时器的清除方法

    vue路由事件beforeRouteLeave及组件内定时器的清除方法

    今天小编就为大家分享一篇vue路由事件beforeRouteLeave及组件内定时器的清除方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-09-09
  • vue中使用 pinia 全局状态管理的实现

    vue中使用 pinia 全局状态管理的实现

    本文主要介绍了vue中使用 pinia 全局状态管理的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-07-07
  • jenkins自动构建发布vue项目的方法步骤

    jenkins自动构建发布vue项目的方法步骤

    这篇文章主要介绍了jenkins自动构建发布vue项目的方法步骤,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-01-01
  • Vue实现一个无限加载列表功能

    Vue实现一个无限加载列表功能

    这篇文章主要介绍了Vue实现一个无限加载列表功能,需要的朋友可以参考下
    2018-11-11
  • vue3如何使用provide实现状态管理详解

    vue3如何使用provide实现状态管理详解

    Vue3中有一对新增的api,provide和inject,熟悉Vue2的朋友应该明,这篇文章主要给大家介绍了关于vue3如何使用provide实现状态管理的相关资料,需要的朋友可以参考下
    2021-10-10
  • el-date-picker日期时间选择器的选择时间限制到分钟级别

    el-date-picker日期时间选择器的选择时间限制到分钟级别

    文章介绍了如何使用el-date-picker 组件来限制用户选择的时间,禁止选择当前时间的日期及时分,同时允许选择其他日期的全天时分,通过设置 `pickerOptions` 对象的属性,可以实现对日期和时间的精确控制,感兴趣的朋友跟随小编一起看看吧
    2025-01-01
  • bmob js-sdk 在vue中的使用教程

    bmob js-sdk 在vue中的使用教程

    将bmob js-sdk放在static目录,然后在index.html页面中已 script 标签的形式引入,就可以在vue中全局使用bmob js-sdk。下面通过本文给大家分享bmob js-sdk 在vue中的使用教程,需要的朋友参考下吧
    2018-01-01
  • Vue在外部配置打包文件夹名称和url地址前缀

    Vue在外部配置打包文件夹名称和url地址前缀

    本文主要介绍了Vue在外部配置打包文件夹名称和url地址前缀,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-06-06
  • Vue Router路由hash模式与history模式详细介绍

    Vue Router路由hash模式与history模式详细介绍

    Vue Router是Vue.js官方的路由管理器。它和Vue.js的核心深度集成,让构建单页面应用变得易如反掌。路由实际上就是可以理解为指向,就是我在页面上点击一个按钮需要跳转到对应的页面,这就是路由跳转
    2022-08-08
  • antd vue 如何调整checkbox默认样式

    antd vue 如何调整checkbox默认样式

    这篇文章主要介绍了antd vue 如何调整checkbox默认样式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-12-12

最新评论