Vue3 动态ref问题及解决

 更新时间:2025年07月23日 15:32:09   作者:linab112  
Vue3动态ref在组件卸载后保留key,值置为null,需手动检查null以避免错误,不可删除key,此为设计行为,旨在维护响应式结构完整性及性能优化

1.问题描述

在Vue 3项目中,当使用动态ref来引用组件时,删除组件后发现ref对象中对应的key仍然存在,只是值变为`null`,而不是完全删除该key。

在一个可拖拽的卡片列表组件中:

  • 使用动态ref来引用每个卡片中的数据列表组件
  • 当删除卡片时,需要同时清理对应的ref引用
  • 发现删除后ref对象中key仍存在,值为`null`

2.示例代码

<template>
  <div>
    <a-card v-for="item in dragList" :key="item.id">
      <!-- 动态ref的使用 -->
      <data-list 
        :ref="el => { dataListRef[item.id] = el }" 
        :doc-id="item.id"
        :open-type="item.openType"
      />
    </a-card>
  </div>
</template>
<script setup lang="ts">
import { ref } from 'vue';

const dragList = ref<any[]>([]);
const dataListRef = ref<Record<string, any>>({});

// 删除卡片方法
function remove(index: number) {
  const current = dragList.value[index];

  // 处理编辑状态
  if (current.openType === OPEN_WRITE) {
    const docIds = [current.id];
    closeDocEntry(docIds);
  }

  // 从列表中移除
  dragList.value.splice(index, 1);

  // 更新其他项目的源列表
  for (let ele of dragList.value) {
    const oldSourceList = ele.sourceList;
    ele.sourceList = oldSourceList.filter((item: any) => item.sourceId !== current.id);
  }

  // Vue 会自动处理动态 ref 的清理,无需手动删除,即使执行了删除方法,也不会删除key
  // dataListRef.value[current.id] 会自动变为 null
}

// 刷新所有数据列表
function reflushAllDragList() {
  Object.keys(dataListRef.value).forEach((key: string) => {
    // 过滤掉已经被删除的组件(值为null的情况)
    if (dataListRef.value[key]) {
      dataListRef.value[key].refresh();
    }
  });
}
</script>

说明:

①可以使用数组或者对象存储组件的ref对象实例,因为组件是循环生成的,所以每个组件的ref对象需要通过这种方式进行存储。

② 循环生成的多个组件可以通过点击删除按钮进行删除,当组件删除时原本想删除ref对象中的组件对应的ref对象,但发现无法删除,最后的结果是key存在,value为null

3.原因分析

Vue 3中的动态ref机制有以下特点:

  • 组件挂载时:动态ref会自动将组件实例赋值给指定的key
  • 组件卸载时:Vue会自动将对应的ref值设置为`null`,但**不会删除key**
  • 响应式处理:Vue的响应式系统会在组件生命周期中自动管理ref的状态

为什么key不会被删除

这是Vue 3的设计行为,不是bug:

  • Vue需要保持ref对象的响应式结构完整性
  • 避免在组件频繁挂载/卸载时产生不必要的响应式触发
  • 提供了更好的性能优化

4.解决方案

因为无法删除,所以在后续使用ref对象时,需要进行判断是否为null,如果不为null,则执行相关方法。

function reflushAllDragList() {
  Object.keys(dataListRef.value).forEach((key: string) => {
    // 过滤掉已经被删除的组件(值为null的情况)
    // 当删除card时,Vue会自动把dataListRef的对应key的值设置为null
    // 不用进行手动删除,即使手动删除,key也存在
    if (dataListRef.value[key]) {
      dataListRef.value[key].refresh();
    }
  });
}

5.总结

Vue 3的动态ref在组件卸载时会自动将值设置为`null`但保留key,这是正常的设计行为。

正确的处理方式是:

  • 不要尝试手动删除ref中的key
  • 在使用ref时进行null检查
  • 信任Vue的自动管理机制

这样可以确保代码的稳定性和可维护性。

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

相关文章

  • Vue导出excel的两个常用方式介绍与对比

    Vue导出excel的两个常用方式介绍与对比

    这篇文章主要为大家详细介绍了Vue导出excel的两个常用方式,分别为前端vue+XLSX导出excel和vue+后端POI 导出excel,感兴趣的小伙伴可以了解下
    2025-01-01
  • vue实现动态绑定行内样式style的backgroundImage

    vue实现动态绑定行内样式style的backgroundImage

    这篇文章主要介绍了vue实现动态绑定行内样式style的backgroundImage方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-07-07
  • antd Vue实现Login登录页面布局案例详解 附带验证码验证功能

    antd Vue实现Login登录页面布局案例详解 附带验证码验证功能

    这篇文章主要介绍了antd Vue实现Login登录页面布局案例详解附带验证码验证功能,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-05-05
  • Vue引入echarts方法与使用介绍

    Vue引入echarts方法与使用介绍

    Echarts,它是一个与框架无关的 JS 图表库,但是它基于Js,这样很多框架都能使用它,例如Vue,估计IONIC也能用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-08-08
  • vue中动态参数与计算属性的使用方法

    vue中动态参数与计算属性的使用方法

    在平时vue开发中,我们经常会用到计算属性(计算属性只有在它的相关依赖发生改变时才会重新求值)来计算我们需要的数据,下面这篇文章主要给大家介绍了关于vue中动态参数与计算属性使用的相关资料,需要的朋友可以参考下
    2021-08-08
  • vue-cli 3.0 引入mint-ui报错问题及解决

    vue-cli 3.0 引入mint-ui报错问题及解决

    这篇文章主要介绍了vue-cli 3.0 引入mint-ui报错问题及解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-05-05
  • Vue+OpenLayers进行项目开发的完整指南

    Vue+OpenLayers进行项目开发的完整指南

    在前端开发中,OpenLayers 是一个强大的开源地图库,可以用于 WebGIS 开发,下面小编就来和大家详细讲讲Vue使用OpenLayers进行项目开发的具体步骤
    2025-06-06
  • 前端vue按1920*1080设计图的页面适配屏幕缩放并适配4K屏详解

    前端vue按1920*1080设计图的页面适配屏幕缩放并适配4K屏详解

    最近在做一个数据可视化的项目,整个项目全是大屏展示,期间也是遇到很多问题,最令人头疼的就是大屏的适配,下面这篇文章主要给大家介绍了前端vue按1920*1080设计图的页面适配屏幕缩放并适配4K屏的相关资料,需要的朋友可以参考下
    2022-11-11
  • vue导出excel表格并支持样式及行高修改

    vue导出excel表格并支持样式及行高修改

    这篇文章主要为大家介绍了vue导出excel表格并支持样式及行高修改,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-06-06
  • vue-cli4创建项目导入Element-UI踩过的坑及解决

    vue-cli4创建项目导入Element-UI踩过的坑及解决

    这篇文章主要介绍了vue-cli4创建项目导入Element-UI踩过的坑及解决,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-04-04

最新评论