v-slot not working on component if mixing default and named slots - compiler error not helpful
Vue version
3.2
Link to minimal reproduction
https://stackblitz.com/edit/vue-ygckrr?file=src/App.vue
Steps to reproduce
- Create a component with default slot, and named slots
- On the Parent, use this component attaching
v-slot
on the component itself, and attach the method on a button. - The template won't compile
TabSelector
<template>
<div>
<slot :set-tab="setTab" />
</div>
<slot :name="modelvalue" />
</template>
App.vue
<script lang="ts" setup>
import { ref } from 'vue';
import TabSelector from './TabSelector.vue';
const currentTab = ref<'a' | 'b' | 'c'>('a');
</script>
<template>
<TabSelector v-model="currentTab" v-slot="{ setTab }">
<button @click="setTab('a')">
Click on A
</button>
<button @click="setTab('b')">
Click on B
</button>
<button @click="setTab('c')">
Click on B
</button>
<template #a>
This is A content
</template>
<template #b>
This is A content
</template>
<template #c>
This is A content
</template>
</TabSelector>
</template>
What is expected?
I shouldn't have to add an additional template tag to be able to use the scoped slot methods like this:
<template>
<TabSelector v-model="currentTab">
<template #default="{ setTab }"
<div>
<button @click="setTab('a')">Click on A</button>
<button @click="setTab('b')">Click on B</button>
<button @click="setTab('c')">Click on B</button>
</div>
</template>
<template #a>A</template>
<template #b>B</template>
<template #c>C</template>
</TabSelector>
</template>
What is actually happening?
It won't compile, and the message error is not clear.
Codegen node is missing for element/if/for node. Apply appropriate transforms first.
on StackBlitz, and Uncaught TypeError: can't access property "name", AppComponent is undefined
on https://sfc.vuejs.org
System Info
No response
Any additional comments?
I have reasons to believe this is normal behaviour, however it is not documented and it took me time to guess it.
This is indeed expected behavior. Logically, if we allowed this template hierarchy, people would also expect to be able to use slot props from the default slot in the content of a named slot, because that's what the template would suggest:
<template>
<TabSelector v-model="currentTab" v-slot="{ setTab }">
<button @click="setTab('a')">
Click on A
</button>
<template #a>
This is A content
<button @click="setTab('b')">
Click on B
</button>
<button @click="setTab('c')">
Click on B
</button>
</template>
<template #b>
This is A content
</template>
<template #c>
This is A content
</template>
</TabSelector>
</template>
...but that does not work, as the named slots are not really nested in the default slot.
- The compiler hints could be better though.
- And this could be explained more clearly in the docs. Right now it's merely hinted at. I think the docs team would apprechiate if you could open a separate issue for this.