Vue.js Slots

Vue.js Slots are a powerful feature that allows developers to create flexible and reusable components by letting them inject content into child components. Slots provide a way to compose components in a way that allows for custom content while maintaining the component's encapsulation and reusability. This chapter will cover everything you need to know about Vue.js slots, from basic concepts to advanced techniques, complete with examples and detailed explanations.

What are Slots?

Slots in Vue.js are placeholder elements in child components that allow content to be passed from a parent component. This mechanism makes it possible to create highly flexible and reusable components.

Basic Slots

Default Slots

Default slots allow you to pass content into a component without specifying a name for the slot.

				
					<div id="app">
  <simple-component>
    <p>This is passed from the parent.</p>
  </simple-component>
</div> <script type="litespeed/javascript">Vue.component('simple-component',{template:'<div><slot></slot></div>'});new Vue({el:'#app'})</script> 
				
			

Explanation:

  • The simple-component has a <slot></slot> element in its template.
  • The content inside the simple-component tags in the parent (<p>This is passed from the parent.</p>) is inserted into the slot.
  • The output will be <div><p>This is passed from the parent.</p></div>.

Named Slots

Named slots allow you to define multiple slots in a component and pass content to specific slots.

				
					<div id="app">
  <named-slot-component>
    <template v-slot:header>
      <h1>This is the header</h1>
    </template>
    <template v-slot:footer>
      <p>This is the footer</p>
    </template>
  </named-slot-component>
</div> <script type="litespeed/javascript">Vue.component('named-slot-component',{template:`
    <div>
      <header><slot name="header"></slot></header>
      <footer><slot name="footer"></slot></footer>
    </div>
  `});new Vue({el:'#app'})</script> 
				
			

Explanation:

  • The named-slot-component defines two slots with names header and footer.
  • The parent component uses <template v-slot:header> and <template v-slot:footer> to pass content to these named slots.
				
					Output:
<div>
  <header><h1>This is the header</h1></header>
  <footer><p>This is the footer</p></footer>
</div>

				
			

Scoped Slots

Scoped slots allow a child component to pass data back to the parent scope where the slot content is defined.

				
					<div id="app">
  <scoped-slot-component>
    <template v-slot:default="slotProps">
      <p>Message from child: {{ slotProps.msg }}</p>
    </template>
  </scoped-slot-component>
</div> <script type="litespeed/javascript">Vue.component('scoped-slot-component',{template:'<div><slot :msg="message"></slot></div>',data(){return{message:'Hello from the child component!'}}});new Vue({el:'#app'})</script> 
				
			

Explanation:

  • The scoped-slot-component provides a msg property to the slot using <slot :msg="message"></slot>.
  • The parent component accesses this property using slotProps.msg.
  • The output will be <div><p>Message from child: Hello from the child component!</p></div>.

Default Slot Content

Default slot content is displayed if no content is provided by the parent component.

				
					<div id="app">
  <default-slot-component></default-slot-component>
</div> <script type="litespeed/javascript">Vue.component('default-slot-component',{template:'<div><slot>This is default content.</slot></div>'});new Vue({el:'#app'})</script> 
				
			

Explanation:

  • The default-slot-component provides default content inside the <slot> tag.
  • Since no content is passed from the parent, the default content is displayed.
  • The output will be <div>This is default content.</div>

Fallback Content for Slots

Fallback content is used to provide default content for named slots when no content is passed.

				
					<div id="app">
  <fallback-slot-component></fallback-slot-component>
</div> <script type="litespeed/javascript">Vue.component('fallback-slot-component',{template:`
    <div>
      <slot name="header">Default Header</slot>
      <slot name="footer">Default Footer</slot>
    </div>
  `});new Vue({el:'#app'})</script> 
				
			

Explanation:

  • The fallback-slot-component provides default content for the header and footer slots.
  • Since no content is passed for these slots, the default content is displayed.
				
					Output:
<div>
  <header>Default Header</header>
  <footer>Default Footer</footer>
</div>

				
			

Named Slots

Named slots allow you to define multiple slots and assign names to them for better content organization.

				
					<div id="app">
  <named-slot-component>
    <template v-slot:header>
      <h1>This is the header</h1>
    </template>
    <template v-slot:footer>
      <p>This is the footer</p>
    </template>
  </named-slot-component>
</div> <script type="litespeed/javascript">Vue.component('named-slot-component',{template:`
    <div>
      <header><slot name="header"></slot></header>
      <footer><slot name="footer"></slot></footer>
    </div>
  `});new Vue({el:'#app'})</script> 
				
			

Explanation:

  • Named slots header and footer are defined in the named-slot-component.
  • The parent component uses <template v-slot:header> and <template v-slot:footer> to pass content to these slots.
				
					<div>
  <header><h1>This is the header</h1></header>
  <footer><p>This is the footer</p></footer>
</div>

				
			

Scoped Slots

Scoped slots allow a child component to pass data back to the parent scope where the slot content is defined. This makes slots more dynamic and flexible.

				
					<div id="app">
  <scoped-slot-component>
    <template v-slot:default="slotProps">
      <p>Message from child: {{ slotProps.msg }}</p>
    </template>
  </scoped-slot-component>
</div> <script type="litespeed/javascript">Vue.component('scoped-slot-component',{template:'<div><slot :msg="message"></slot></div>',data(){return{message:'Hello from the child component!'}}});new Vue({el:'#app'})</script> 
				
			

Explanation:

  • The scoped-slot-component provides a msg property to the slot using <slot :msg="message"></slot>.
  • The parent component accesses this property using slotProps.msg.
  • The output will be <div><p>Message from child: Hello from the child component!</p></div>.

Using Scoped Slots for Complex Data

Scoped slots can be used to pass complex data structures from the child to the parent component.

				
					<div id="app">
  <complex-scoped-slot>
    <template v-slot:default="slotProps">
      <p>Title: {{ slotProps.data.title }}</p>
      <p>Content: {{ slotProps.data.content }}</p>
    </template>
  </complex-scoped-slot>
</div> <script type="litespeed/javascript">Vue.component('complex-scoped-slot',{template:'<div><slot :data="postData"></slot></div>',data(){return{postData:{title:'Post Title',content:'This is the post content.'}}}});new Vue({el:'#app'})</script> 
				
			

Explanation:

  • The complex-scoped-slot component provides a data property to the slot using <slot :data="postData"></slot>.
  • The parent component accesses this property using slotProps.data.
				
					Output:
<div>
  <p>Title: Post Title</p>
  <p>Content: This is the post content.</p>
</div>

				
			

Dynamic Slots

Dynamic slots allow you to determine the slot to use at runtime based on dynamic data.

				
					<div id="app">
  <dynamic-slot-component>
    <template v-slot:header>
      <h1>This is the header</h1>
    </template>
    <template v-slot:footer>
      <p>This is the footer</p>
    </template>
  </dynamic-slot-component>
</div> <script type="litespeed/javascript">Vue.component('dynamic-slot-component',{template:`
    <div>
      <slot :name="currentSlot"></slot>
    </div>
  `,data(){return{currentSlot:'header'}},created(){setTimeout(()=>{this.currentSlot='footer'},2000)}});new Vue({el:'#app'})</script> 
				
			

Explanation:

  • The dynamic-slot-component has a slot name determined by the currentSlot data property.
  • Initially, currentSlot is set to header, so the header slot content is displayed.
  • After 2 seconds, currentSlot is changed to footer, displaying the footer slot content.
  • The output will initially be <h1>This is the header</h1>, and after 2 seconds it will change to <p>This is the footer</p>.

Best Practices for Using Slots

  • Keep Slots Simple: Use slots to keep components simple and focused on their purpose.
  • Use Scoped Slots Wisely: Pass data back to parent components using scoped slots to create more dynamic and flexible components.
  • Fallback Content: Always provide fallback content for slots to handle cases where no content is provided by the parent.
  • Document Slot Usage: Clearly document the expected slot content and any scoped properties to make components easier to understand and use.
  • Avoid Overuse: While slots are powerful, overusing them can lead to complex and hard-to-maintain code. Use them judiciously.

Vue.js slots are a versatile tool for creating flexible and reusable components. By understanding how to use default slots, named slots, scoped slots, and dynamic slots, you can build components that can be easily customized and extended. Proper use of slots helps maintain the separation of concerns and keeps components modular and maintainable. With this comprehensive guide, you now have the knowledge to effectively utilize slots in your Vue.js applications, enhancing their flexibility and reusability.Happy coding !❤️

Table of Contents