Vue3中如何从父组件访问插槽传入组件的defineExpose暴露内容?
问题:如何在Component.vue中访问子组件暴露的属性
Component.vue
<template> <div> <div class="items"> <slot name="items"></slot> </div> <div class="controller"></div> <slot name="controller"></slot> </div> </template> <script lang="ts" setup> // 此处需要访问父组件传入到'items'插槽的所有组件的暴露属性 </script>
ComponentChild.vue
<template> <div ref="el" class="item"> <slot></slot> </div> </template> <script lang="ts" setup> import { ref, onMounted } from 'vue' const el = ref<HTMLDivElement>() const itemEl = ref<HTMLElement>() onMounted(() => { itemEl.value = el.value!.children[0] as HTMLElement }) defineExpose({ itemElement: itemEl, }) </script>
使用示例
<template> <div> <Component> <template #items> <ComponentChild v-for="item in items" :key="item.id"> <div>The element I'm trying to access from Component exposed as itemElement in ComponentChild</div> </ComponentChild> </template> <template #controller> <div>...</div> </template> </Component> </div> </template> <script lang="ts" setup> import Component from "@/components/Component.vue" import ComponentChild from "@/components/ComponentChild.vue" </script>
问题描述
如何在Component.vue中访问每个ComponentChild组件通过defineExpose暴露的itemElement属性?(注:已知此获取元素ref的方式并非最优,但需关注如何访问子组件暴露的内容,无需提供替代方案。)
解决方案
要访问插槽内子组件暴露的属性,可通过useSlots获取插槽内容,结合vnode的component属性拿到子组件的暴露对象,具体实现如下:
- 在
Component.vue的<script setup>中导入所需API:
import { useSlots, onMounted } from 'vue'
- 在组件挂载完成后,遍历
items插槽的节点,获取子组件暴露的属性:
const slots = useSlots() onMounted(() => { // 获取items插槽的所有节点 const itemsSlotNodes = slots.items?.() || [] // 遍历节点,筛选并访问ComponentChild的暴露属性 itemsSlotNodes.forEach(node => { // 判定当前节点为组件类型vnode if (node.component) { const exposedProps = node.component.exposed if (exposedProps) { // 此处即可拿到子组件暴露的itemElement console.log(exposedProps.itemElement.value) } } }) })
注意事项:
- 必须在
onMounted钩子中执行逻辑,此时子组件已完成挂载,exposed属性才会包含暴露的内容。 - 如果插槽内的
ComponentChild外层嵌套了其他元素,需要递归遍历vnode的children节点来定位目标组件。
内容的提问来源于stack exchange,提问作者FieryRider
相关产品推荐
相关产品推荐

