Loading source
Pulling the file list, source metadata, and syntax-aware rendering for this listing.
Source from repo
Vue 3 debugging reference for reactivity issues, computed errors, watcher bugs, async failures, and SSR hydration problems.
Files
Skill
Size
Entrypoint
Format
Open file
Syntax-highlighted preview of this file as included in the skill package.
reference/slot-named-scoped-explicit-default.md
1---2title: Use Explicit Default Template When Mixing Named and Scoped Slots3impact: HIGH4impactDescription: Mixing v-slot on component with named slots inside causes ambiguous scope and compilation errors5type: gotcha6tags: [vue3, slots, scoped-slots, named-slots, compilation-error]7---89# Use Explicit Default Template When Mixing Named and Scoped Slots1011**Impact: HIGH** - When a component uses both the default scoped slot and named slots, you must use an explicit `<template #default>` for the default slot. Using `v-slot` directly on the component while having nested named slot templates causes scope ambiguity and compilation errors.1213## Task Checklist1415- [ ] When using named slots alongside a default slot with props, always use explicit `<template #default>`16- [ ] Never mix `v-slot` on the component element with `<template #name>` inside17- [ ] Keep slot scope clear and unambiguous1819**Incorrect:**20```vue21<script setup>22import MyComponent from './MyComponent.vue'23</script>2425<template>26<!-- BAD: v-slot on component + named template inside causes ambiguity -->27<MyComponent v-slot="{ message }">28<p>{{ message }}</p>2930<template #footer>31<!-- Ambiguous: Is 'message' available here? Vue can't determine -->32<p>Footer: {{ message }}</p>33</template>34</MyComponent>35</template>36```3738This causes a compilation error because Vue cannot determine:391. Whether `message` from the default slot should be available in the footer slot402. Which scope applies to the non-template content4142**Correct:**43```vue44<script setup>45import MyComponent from './MyComponent.vue'46</script>4748<template>49<!-- GOOD: Explicit template for each slot with clear scope -->50<MyComponent>51<template #default="{ message }">52<p>{{ message }}</p>53</template>5455<template #footer>56<!-- Clear: footer slot has its own scope, no access to default's 'message' -->57<p>Footer content here</p>58</template>59</MyComponent>60</template>61```6263**Correct - When Footer Also Has Props:**64```vue65<script setup>66import MyComponent from './MyComponent.vue'67</script>6869<template>70<MyComponent>71<template #default="{ message }">72<p>{{ message }}</p>73</template>7475<template #footer="{ year }">76<!-- Each slot receives its own props -->77<p>Copyright {{ year }}</p>78</template>79</MyComponent>80</template>81```8283## The Rule8485When you have **any** named slots (`<template #name>`), always use explicit templates for **all** slots, including the default slot. This makes scope boundaries clear and prevents compilation errors.8687| Pattern | Valid? | Notes |88|---------|--------|-------|89| `v-slot` on component only | Yes | Single default scoped slot |90| Named templates only | Yes | Multiple named slots |91| `v-slot` on component + named templates | No | Ambiguous scope |92| All explicit templates | Yes | Clear scope for each slot |9394## Reference95- [Vue.js Slots - Named Scoped Slots](https://vuejs.org/guide/components/slots.html#named-scoped-slots)96