Debug School

rakesh kumar
rakesh kumar

Posted on

Explain Slots and its Different Types

the-difference-between-props-slots-and-scoped-slots-in-vue-js
vue-dot-js-slots
the-difference-between-props-slots-and-scoped-slots-in-vue-js
using-slots-vue-js

QUESTION:
the-difference-between-props-slots-and-scoped-slots-in-vue-js
the-difference-between-props-slots-and-scoped-slots-in-vue-js

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

Let’s see what is the best way to pass data between components
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.

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!

Introduction to Vue.js slots

vue-dot-js-slots
As we all have heard a lot about the Vue.js, which is basically an open-source javascript framework used to create web interfaces. Vue provides a lot of features and benefits to the programmer, which makes it very easy to create applications in it. Slots are one of the most powerful tools of the Vue.js framework, which helps in creating generic components other than the strict parent-child relationship. Slots allow the parent to inject any type of content in the child component. Slots are used for creating reusable components, which make things easier to create for programmers.

Syntax:

Below given is the basic syntax of using the slots in the Vue.js framework:

<template>
<div class =”new-class”>
<slot>
…...content of the slot to be written here…….
</slot>
</div>
</template>
Enter fullscreen mode Exit fullscreen mode

is used like the basic html tag with the opening and closing braces. In the above code, is used inside the parent component. We can insert any html tags like

,

, etc. in between the tag.

How do slots work in Vue.js?
Vue. js allows the passing of string, arrays, etc., from one component to another. It also allows the passing of html content from parent component to child component through the use of slots. But have you ever thought about why this passing of the html component is required? By passing string values in components, cross-scripting attacks on the web interfaces become very easy for the hackers. This issue can be resolved by slots in Vue.js by the passing of html content as the website becomes less vulnerable to such kinds of attacks.

In order to have a deep understanding of slots in the Vue.js javascript framework, we first need to understand few concepts related to it:

  1. Basic Working Whatever the content or the html tags passed from the parent component through the tags, it gets rendered in the tag of the child component.

Let us understand its working with the help of an example.

Example:

Child.vue

<template>
<div class = “my_child”>
<slots>
</slots>
</div>
</template>

Parent.vue

<template>
<div class = “my_parent”>
<child-component>
<h1> I am from parent component </h1>
<h2> I will get rendered in the child component </h2>
<p> This is the basic working of slots tag </p>
</div>
</template>
<script>
import Child from ‘./Child.vue’
export default {
components: {
Child
}
}
</script>

In the above code, as we have imported the Child.vue component in parent, so the content written inside the tags, i.e. the headings

,

and paragraph

of the parent component ‘Parent.vue’ will get rendered in the tag of the child component ‘Child.vue’.

  1. Content Fallback If the parent component does not pass anything between the and tags, then the content or the tags, whatever is written inside these tags, are rendered by default.

Example:

Child.vue

<template>
<div class =”child”>
<slots>
This is the default content which will be displayed if nothing is passed
</slots>
</div>
</template>

Parent.vue

<template>
<div class = “parent”>
<child-component> </child-component>
</div>
</template>
<script>
import Child from ‘./Child.vue’
export default {
components: {
Child
}
}
</script>

In the above code, we have not passed anything to be rendered in the tags that will get rendered in the tags of Chile.vue component. So the default content is written in tag of Parent.vue file, i.e., this is the default content that will be displayed if nothing is passed.

Types of slots along with Examples in Vue.js
Let us see the types of slots along with their examples in the Vue.js to dive deep in it.

  1. Scoped slots Scoped slots are some different kinds of slots which are basically used when we want to access the properties of a child component from the parent component. They allow us to pass the property values from the child and access them in the parent component. The thumb rule of using the scoped slot is to pass the property values in the Child component only through the default or scoped slot.

Example:

Child.vue

<template>
<div class = “child-class”>
<slot name = “child-slot1” : text = “text1”> </slot>
<slot name =”child-slot2” : text = “text2”> </slot>
</div>
</template>
export default {
data()  {
return  {
child-slot1: “this is the content of child-slot”,
child-slot2: “this is the content of child-slot2”
}
}
}
</script>

In order to access the properties of the child component, we need to create a template element and use the scope attribute with the name attached to that in the parent component.

Parent.vue

<template>
<div class =”parent-template”>
<child-component>
<template slot=”child-slot1” slot- scope =”scoped-template1”>
<h1> {scoped-template1.text} </h1>
</template>
<template slot=”child-slot2” slot- scope =”scoped-template2”>
<h1> {scoped-template2.text} </h1>
</template>
</child-component>
</div>
</template>
<script>
import Child from ‘./Child.vue’
export default {
components: {
Child
}
}
</script>
  1. Named slots As the name indicates, named slots are the one with the name attributes with the slots tag. These named slots are useful when we want to inject different content at different positions of the component.

Example:

Child.vue:

<template>
<div class = “child-template”>
<slots name =”slot1”>
</slots>
<slots name = “slot2”>
</slots>
</div>
</template>

Parent.vue:

<template>
<div class = “parent-template”>
<template #slot1>
<h1> I am in parent component </h1>
<p> This is the paragraph of parent component of slot1 </p>
</template>
<template #slot2>
<h2> I am in heading 2 of parent component </h2>
<p> This is paragraph of parent component of slot2 </p>
</template>
</div>
</template>
<script>
import Child from ‘./Child.vue’
export default {
components: {
Child
}
}
</script>

In the above code, we have imported the child component ‘Child.vue’ in the parent component and created the 2 different named slots ‘slot1’ and ‘slot2’ to insert different content at different positions. Both the slots are used with ‘#’ in the parent, as this is the shortcut to use the named slot.

PROPS

https://medium.com/notonlycss/the-difference-between-props-slots-and-scoped-slots-in-vue-js-a697b57099ee

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 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.


Top comments (0)