Vue3父组件挂载后,循环渲染的子组件Ref始终为空如何解决?
问题原因及解决方法
核心原因:DOM更新的异步性
你在onMounted里通过await fetchEntries()获取数据后,Vue会把DOM更新操作放入异步队列,不会立即执行。onMounted钩子执行完毕时,DOM还没完成渲染,所以entryComponentsRefs此时仍是空数组。
具体解决步骤
1. 等待DOM更新完成后访问refs
使用nextTick等待Vue完成DOM更新,之后就能拿到填充后的refs数组:
<script setup> // ...imports import { ref, onMounted, nextTick } from 'vue'; const entries = ref([]); const entryComponentsRefs = ref([]); onMounted(async () => { entries.value = await fetchEntries(); // 等待DOM更新完成 await nextTick(); // 此时entryComponentsRefs已填充对应组件实例 console.log(entryComponentsRefs.value); }); </script>
2. 确保Entry组件允许外部获取实例
如果Entry是用<script setup>编写的组件,默认会关闭实例暴露,需要显式允许外部获取:
在Entry.vue中添加:
<script setup> // ...其他代码 // 暴露组件实例或需要的方法/属性 defineExpose({ // 示例:暴露获取根元素的方法,用于滚动定位 getRootElement() { return $el; } }); </script>
3. 直接绑定DOM元素ref(若无需组件实例)
如果仅需获取DOM元素用于滚动,不需要Entry组件实例,可以直接在组件根元素上绑定ref:
<template> <Container> <Entry v-for="entry in entries" :key="entry.id" :ref="el => { el && entryComponentsRefs.value.push(el) }" /> </Container> </template>
这种方式能直接拿到DOM元素,无需处理组件实例暴露逻辑。
内容的提问来源于stack exchange,提问作者starleaf1
相关产品推荐
相关产品推荐

