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-render-scope-parent-only.md
1---2title: Slot Content Only Has Access to Parent Component Scope3impact: HIGH4impactDescription: Attempting to access child component data in slot content results in undefined values or errors5type: gotcha6tags: [vue3, slots, scope, reactivity, common-mistake]7---89# Slot Content Only Has Access to Parent Component Scope1011**Impact: HIGH** - Slot content is compiled in the parent component's scope and cannot access data defined in the child component. This follows JavaScript's lexical scoping rules and is a common source of confusion.1213When you provide content for a slot, that content is defined in your parent template and can only access data available in the parent component. The child component's internal state is not accessible unless explicitly passed via scoped slots.1415## Task Checklist1617- [ ] Remember that slot content is compiled in parent scope18- [ ] Never try to access child component data directly in slot content19- [ ] Use scoped slots when child data needs to be exposed to parent20- [ ] Check that all template expressions reference data available in the current component2122**Incorrect:**23```vue24<!-- Parent.vue -->25<script setup>26import SubmitButton from './SubmitButton.vue'27</script>2829<template>30<!-- BAD: Trying to access child's buttonText - this will be undefined -->31<SubmitButton>{{ buttonText }}</SubmitButton>3233<!-- BAD: Trying to access child's isLoading state -->34<SubmitButton>35<span v-if="isLoading">Loading...</span>36<span v-else>Submit</span>37</SubmitButton>38</template>39```4041```vue42<!-- SubmitButton.vue (Child) -->43<script setup>44import { ref } from 'vue'4546const buttonText = ref('Click me') // Not accessible in parent's slot content47const isLoading = ref(false) // Not accessible in parent's slot content48</script>4950<template>51<button>52<slot></slot>53</button>54</template>55```5657**Correct - Use Scoped Slots:**58```vue59<!-- SubmitButton.vue (Child) - Expose data via slot props -->60<script setup>61import { ref } from 'vue'6263const buttonText = ref('Click me')64const isLoading = ref(false)65</script>6667<template>68<button>69<!-- Pass child data as slot props -->70<slot :text="buttonText" :loading="isLoading"></slot>71</button>72</template>73```7475```vue76<!-- Parent.vue -->77<script setup>78import SubmitButton from './SubmitButton.vue'79</script>8081<template>82<!-- GOOD: Receive child data via scoped slot -->83<SubmitButton v-slot="{ text, loading }">84<span v-if="loading">Loading...</span>85<span v-else>{{ text }}</span>86</SubmitButton>87</template>88```8990**Correct - Use Parent Data:**91```vue92<!-- Parent.vue -->93<script setup>94import { ref } from 'vue'95import SubmitButton from './SubmitButton.vue'9697// Define data in parent where slot content is compiled98const message = ref('Submit Form')99const isSubmitting = ref(false)100</script>101102<template>103<!-- GOOD: Using parent's own data in slot content -->104<SubmitButton>105<span v-if="isSubmitting">Processing...</span>106<span v-else>{{ message }}</span>107</SubmitButton>108</template>109```110111## The Function Analogy112113Think of slots as function parameters:114115```javascript116// Slot content is like a callback defined in parent scope117function Parent() {118const parentData = 'Hello'119120// This callback can only see parentData, not childData121Child((slotProps) => {122return parentData + (slotProps?.text || '')123})124}125126function Child(slotCallback) {127const childData = 'World' // Not visible to callback128129// Must explicitly pass data via slot props130return slotCallback({ text: childData })131}132```133134## Reference135- [Vue.js Slots - Render Scope](https://vuejs.org/guide/components/slots.html#render-scope)136