-
-
Notifications
You must be signed in to change notification settings - Fork 8.9k
Description
Version
3.2.13
Reproduction link
Steps to reproduce
Parent.vue
<template>
<Demo v-slot="{ item }">
<div>{{ item }}</div>
</Demo>
</template>
Child.vue
<template>
<slot :item="111" />
</template>
<script setup>
import { useSlots } from 'vue'
console.log(useSlots().default())
</script>
What is expected?
Prop "item" should be usable (displays "111")
What is actually happening?
Props are undefined. Error Cannot destructure property 'item' of 'undefined' as it is undefined.
I have DataTable
component where columns are defined in slot as DataTableColumn
component for easy usage, like that:
<DataTable
:data="someData"
v-slot="slotProps"
>
<DataTableColumn name="id">
<span class="xxxx">{{ slotProps.item.id }}</span>
</DataTableColumn>
<DataTableColumn name="email">
{{ slotProps.item.email }} {{ slotProps.item.something }} etc
</DataTableColumn>
</DataTable>
I'm getting columns list thanks to useSlots().default()
if (slots.default) {
columns.value = slots.default()
.filter((node) => node.props)
.flatMap((node) => node.props)
}
current item (row) is passed as slot props to parent
<tr
v-for="(item, key) in data"
:key="key"
>
<slot :item="item" />
</tr>
and it works great, I was using similar approach multiple times, also in vue 2.
Problem is that for some reason I cannot use object destructuring on slot props, like that:
<DataTable
:data="someData"
v-slot="{ item }"
>
<DataTableColumn name="id">
<span class="xxxx">{{ item.id }}</span>
</DataTableColumn>
<DataTableColumn name="email">
{{ item.email }} {{ item.something }} etc
</DataTableColumn>
</DataTable>
In console I'm getting
TypeError: Cannot destructure property 'item' of 'undefined' as it is undefined.
It's caused only by using default()
in code. Why it is undefined while firing default()
, even in onMounted()
?
So why is default()
working alone, and { item }
is working alone, but not both combined? For me it's bug, but maybe I'm wrong and someone will clarify this.