The Difference Between Props, Slots and Scoped Slots in Vue.js

Let’s see what is the best way to pass data between components

Luca Spezzano
Oct 26, 2020 · 4 min read
Puzzle
Puzzle
Photo by Bianca Ackermann on Unsplash

When I started using Vue, I just passed data between components through the props, deepening this framework I found that I could achieve the same result with slots.

Let’s understand the differences and the reasons for using props instead of slots and vice versa.

PROPS

They are attributes that are exposed to accept data from the parent component.

Let’s create a component MyMessage with props

<template>
<div class="message">
<h1>{{ msg }}</h1>
</div>
</template>
<script>
export default {
name: "MyMessage",
props: {
msg: String,
},
};
</script>
<style scoped>
.message {
color: red;
text-decoration: underline;
}
</style>

In this way, we are saying that the component accepts a value called msg.

Now when we use this component we are able to pass a value through an attribute

<template>
<my-message msg="NotOnlyCSS is awesome!" />
</template>
<script>
import MyMessage from "./components/MyMessage.vue";
export default {
name: "App",
components: {
MyMessage,
},
};
</script>

You can see the demo and play with props here on codesandbox.

Well I think it is now clear how the props work.

SLOTS

They allow you to compose component, also with HTML code.

Let’s create a component MyMessage with slots

<template>
<div class="message">
<slot />
</div>
</template>
<script>
export default {
name: "MyMessage",
};
</script>
<style scoped>
.message {
color: red;
text-decoration: underline;
}
</style>

In this way, we are saying that the component accepts also a block of code through the slot

Now when we use this component, from the parent we can pass something like this

<template>
<my-message>
<h1>NotOnlyCSS is awesome!</h1>
<p>these are slots</p>
</my-message>
</template>
<script>
import MyMessage from "./components/MyMessage.vue";
export default {
name: "App",
components: {
MyMessage,
},
};
</script>

You can see the demo and play with slots here on codesandbox.

NAMED SLOTS

There are times when it’s useful to have multiple slots, especially for more complex components.

Let’s create a component MyMessage with named slots

<template>
<div>
<header>
<slot name="header"></slot>
</header>
<main>
<slot></slot>
</main>
<footer>
<slot name="footer"></slot>
</footer>
</div>
</template>
<script>
export default {
name: "MyMessage",
};
</script>
<style scoped>
header {
color: red;
text-decoration: underline;
}
footer {
color: blue;
}
</style>

Now when we use this component, from the parent we can pass something like this

<template>
<my-message>
<template v-slot:header>
<h1>NotOnlyCSS is awesome!</h1>
</template>
<template v-slot:default>
<p>A paragraph for the component.</p>
<p>And <b>another</b> one.</p>
</template>
<template v-slot:footer>
<small>The footer of the component</small>
</template>
</my-message>
</template>
<script>
import MyMessage from "./components/MyMessage.vue";
export default {
name: "App",
components: {
MyMessage,
},
};
</script>

You can see the demo and play with named slots here on codesandbox.

Now it’s all clear right?

Working daily with Vue.js I discovered another type of slots, a little more complex but very useful too, they are called scoped slots, t’s go to better understand how they work.

SCOPED SLOTS

Sometimes, it’s useful to have access from the parent to data available in the child component, here scoped slots come in handy.

Let’s create a component MyMessage with scoped slots

<template>
<div class="message">
<slot :firstName="firstName"></slot>
</div>
</template>
<script>
export default {
name: "MyMessage",
data() {
return {
firstName: "Luca",
};
},
};
</script>
<style scoped>
.message {
color: red;
text-decoration: underline;
}
</style>

To make a value available to the slot content provided by the parent, we can add a <slot> element and bind it as an attribute.

Now we are able to access the value firstName also from the parent component like this

<template>
<my-message>
<template v-slot="slotProps">
<h1>Hey {{ slotProps.firstName }}, NotOnlyCSS is awesome!</h1>
</template>
</my-message>
</template>
<script>
import MyMessage from "./components/MyMessage.vue";
export default {
name: "App",
components: {
MyMessage,
},
};
</script>

You can see the demo and play with scoped slots here on codesandbox.

You may be thinking about when scoped slots are useful, a common case is when a component is used to render an array of items, and we want to be able to customize the way each item is rendered.

Conclusion

We have seen many ways of passing data between components, it depends on your needs whether to use props or slots.

With props, you can only pass values to the child component, so the parent wouldn’t be able to customize the child.

If you have a defined design and you just need to change some values, use props!

Slots give you more flexibility and allow you to customize the child component from the parent.

If you want to give the parent the freedom to customize components, use slots!

NotOnlyCSS

This publication includes original articles and tips about…

Sign up for NotOnlyCSS

By NotOnlyCSS

Articles and tips for frontend developers Take a look

By signing up, you will create a Medium account if you don’t already have one. Review our Privacy Policy for more information about our privacy practices.

Check your inbox
Medium sent you an email at to complete your subscription.

Luca Spezzano

Written by

Frontend developer focused on CSS architecture of scalable and maintainable large scale projects and the development of amazing user interfaces.

NotOnlyCSS

This publication includes original articles and tips about frontend technologies.

Luca Spezzano

Written by

Frontend developer focused on CSS architecture of scalable and maintainable large scale projects and the development of amazing user interfaces.

NotOnlyCSS

This publication includes original articles and tips about frontend technologies.

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store