Vue Slots
Slots are a powerful feature in Vue that allow for more flexible and reusable components.
We useslots in Vue to send content from the parent into the<template> of a child component.
Slots
So far we have just used components inside<template> as self-closing tags like this:
App.vue:
<template> <slot-comp /></template>Instead, we can use opening and closing tags, and put some content inside, like for example a text:
App.vue:
<template> <slot-comp>Hello World!</slot-comp></template>But to receive 'Hello World!' inside the component and display it on our page, we need to use the<slot> tag inside the component. The<slot> tag acts as a placeholder for the content, so that after the application is built the<slot> will be replaced by the content sent to it.
Example
SlotComp.vue:
<template> <div> <p>SlotComp.vue</p> <slot></slot> </div></template>Run Example »Slots as Cards
Slots can also be used to wrap around larger chunks of dynamic html content to get a card-like appearance.
Earlier we have sent data as props to create content inside components, now we can just send the HTML content directly inside the<slot> tag as it is.
Example
App.vue:
<template> <h3>Slots in Vue</h3> <p>We create card-like div boxes from the foods array.</p> <div> <slot-comp v-for="x in foods"> <img v-bind:src="x.url"> <h4>{{x.name}}</h4> <p>{{x.desc}}</p> </slot-comp> </div></template>As the content enters the component where the<slot> is, we use a div around the<slot> and style the<div> locally to create a card-like appearance around the content without affecting other divs in our application.
SlotComp.vue:
<template> <div> <!-- This div makes the card-like appearance --> <slot></slot> </div></template><script></script><style scoped> div { box-shadow: 0 4px 8px 0 rgba(0,0,0,0.2); border-radius: 10px; margin: 10px; }</style>Run Example »Components that produce a card-like frame around content can be reused to create different elements, but with the same card-like frame around.
In this example we use the same component as for the food items to create a footer.
Example
App.vue:
<template> <h3>Reusable Slot Cards</h3> <p>We create card-like div boxes from the foods array.</p> <p>We also create a card-like footer by reusing the same component.</p> <div> <slot-comp v-for="x in foods"> <img v-bind:src="x.url"> <h4>{{x.name}}</h4> </slot-comp> </div> <footer> <slot-comp> <h4>Footer</h4> </slot-comp> </footer></template>Run Example »Fallback Content
If a component is created without content we can have fallback content in the<slot>.
Example
The first component in this application has no content provided, so the fallback content is rendered.
App.vue:
<template> <h3>Slots Fallback Content</h3> <p>A component without content provided can have fallback content in the slot tag.</p> <slot-comp> <!-- Empty --> </slot-comp> <slot-comp> <h4>This content is provided from App.vue</h4> </slot-comp></template>SlotComp.vue:
<template> <div> <slot> <h4>This is fallback content</h4> </slot> </div></template>Run Example »
