Scoped slots allow you to pass properties from your child components into a scoped slot, and access them from the parent. Sort of like reverse property passing.
The first step to creating a scoped component slot is to pass properties into a default or named slot from your child component, like so:
ChildComponent.vue
<template>
<div>
<p>Look, there's a slot below me!</p>
<slot :text="defaultSlotText"></slot>
<slot name="literally-the-best" :text="namedSlotText"></slot>
</div>
</template>
<script>
export default {
data() {
return {
defaultSlotText: "I'll get rendered inside the default slot.",
namedSlotText: "I'll get rendered inside the *best* slot."
}
}
}
</script>
Then, to use those properties inside a parent component’s slot content, create a template element tied to the slot.
Add a scope attribute to the template element and set it to the name that you wish to access the scope properties from.
This essentially creates a local variable for anything inside that template, allowing you to access it as if it was in the parent’s scope.
(For example, scope=“myScope”, properties passed into the <slot> will be accessible as {{myScope.myProperty}} while scope=“yourScope” will be accessed as {{yourScope.myProperty}}.)
Note: The template element does not get added to the DOM. It’s simply a wrapper.
ParentComponent.vue
<template>
<div>
<child-component>
<template scope="defaultSlotScope">
<p>{{defaultSlotScope.text}}</p>
<!-- Renders <p>I'll get rendered inside the default slot.</p> -->
</template>
<template slot="literally-the-best" scope="bestSlotScope">
<p>{{bestSlotScope.text}}</p>
<!-- Renders <p>I'll get rendered inside the *best* slot.</p> -->
</template>
</child-component>
</div>
</template>
<script>
import ChildComponent from './ChildComponent.vue';
export default {
components: {
ChildComponent
}
}
</script>
If you’re using Vue 2.5
or above, use the slot-scope
attribute instead of scope
. Also you can skip the template elements.
ParentComponent.vue
<template>
<div>
<child-component>
<p slot-scope="defaultSlotScope">
{{defaultSlotScope.text}}
<!-- Renders <p>I'll get rendered inside the default slot.</p> -->
</p>
<p slot="literally-the-best" slot-scope="bestSlotScope">
{{bestSlotScope.text}}
<!-- Renders <p>I'll get rendered inside the *best* slot.</p> -->
</p>
</child-component>
</div>
</template>
<script>
import ChildComponent from './ChildComponent.vue';
export default {
components: {
ChildComponent
}
}
</script>