v-for渲染的元素上使用ref

在 Vue 3 中,如果你在一个通过 v-for 渲染的元素或组件上直接使用 ref,Vue 会自动将它们收集成一个数组形式的 ref,而不是单个实例。

示例代码:

html 复制代码
<template>
  <div v-for="item in list" :key="item.id" ref="rows">
    {{ item.name }}
  </div>
</template>

<script setup>
import { ref, onMounted } from 'vue'

const list = ref([
  { id: 1, name: '张三' },
  { id: 2, name: '李四' },
  { id: 3, name: '王五' }
])

const rows = ref([])

onMounted(() => {
  console.log(rows.value) 
  // => [HTMLDivElement, HTMLDivElement, HTMLDivElement]
})
</script>

这段代码在 Vue 3 中虽然看似没问题,但存在内存泄漏风险 ------因为直接使用 ref="rows" 在 v-for 内时,Vue 不会在卸载或列表项变化时自动清空旧引用。

进阶写法:

html 复制代码
<template>
  <div
    v-for="item in list"
    :key="item.id"
    :ref="el => setRowRef(el, item.id)"
  >
    {{ item.name }}
  </div>
</template>

<script setup>
import { reactive, nextTick, onBeforeUnmount } from 'vue'

const list = ref([
  { id: 1, name: '张三' },
  { id: 2, name: '李四' },
  { id: 3, name: '王五' }
])

// 用对象代替数组存储 refs,按 id 映射更稳定
const rowRefs = reactive({})

function setRowRef(el, id) {
  if (el) {
    rowRefs[id] = el
  } else {
    // Vue 在节点卸载时会传入 null,这里主动清理引用
    delete rowRefs[id]
  }
}

// 可选:组件卸载时彻底清空引用,防止残留
onBeforeUnmount(() => {
  for (const key in rowRefs) delete rowRefs[key]
})
</script>
相关推荐
liangshanbo12151 小时前
React useEffect 与 useLayoutEffect 面试题整理
前端·javascript·react.js
Bs_MoneyMagnet2 小时前
基于springboot+vue的旅游景区点评系统的设计与实现 源码+文档
java·vue.js·spring boot·后端·spring·旅游
ID34610744202 小时前
【课程设计】基于Spring Boot+Vue的校园共享无人机服务系统设计与实现-计算机毕设 附源码44219
javascript·vue.js·spring boot·python·node.js·php·课程设计
夜不会漫长2 小时前
C++:类和对象(2)
java·javascript·c++
掰头战士2 小时前
聊聊 Function Calling,你的模型是否答非所问?
前端·typescript·agent
Yeyu2 小时前
车载多 App 同屏渲染(三):RemoteCompose 序列化 UI
前端
weixin199701080162 小时前
[特殊字符]《京东POP二手品类对接:B2C订单模型 vs 二手C2C属性的字段转换难题》(附Python源码)
前端·python·算法
BillKu2 小时前
Vue3 可拖拽分栏布局:两种实现方式详解
javascript·vue.js·ecmascript
三小河3 小时前
AI 对话 "打字机" 是怎么实现的?从 SSE 流式、Markdown 组件到 Nginx 防粘连
前端·人工智能·面试
雪芽蓝域zzs3 小时前
第三十七节:防抖、节流封装(composables 通用函数,搜索框防重复请求)
前端·javascript·vue.js