Why Slot is One of the Most Powerful Feature outta VueJs land

ยท

3 min read

Components in VueJs can accept "props".
But these props can only be valid JavaScript values. In a nutshell, if the JavaScript engine can not recognize the props value, they won't be compiled.

Sometimes though we want our props to not only be a value but a component as well. In the react ecosystem, this can be achieved with the "children" props but just as how easily achievable it is, it isn't as elegant as how VueJs sorts itself out with Slot.

What to expect at the end of reading this article

Hopefully, you read to the end,
You would not have only been shown how to better use the slot feature,
but also we will take a quick guide into other brilliant and magical piece that can be done with the slot element.

Dive in

But first: the definition of slot

According to the docs, the slot element is an outlet that tells a child template where the parent-provided slot content should be rendered.

// child template in Button.js
<button>
  <slot></slot> // put a content here
</button>

// parent template in Form.js
<Button>
  join us // replaces the slot element
</Button>

Super-power 1: They're best just an outlet

The slot space takes anything, in any order and it'll be rendered just like that.

// whatever enters the slot space gets mirrored in the child template
<Button>
  <span>Join us</span>
  <Icon />
</Button>

// compiles to 
<button>
    <span>Join us</span>
    <Icon />
</button>

Super-power II: Fallback Content

The fallback content when used will be rendered in place if no content is passed into the slot place when used in its parent component

// child template: Button.js
<button>
  // "Submit" is placed in between the slot element
  <slot>Submit</slot> // ๐Ÿ™Š
</button>

//Parent component
<Button></Button> // realize nothing is in this component ๐Ÿคจ?

// compiles into
<button>Submit</button>

Super-power III: Named Slots

With the addition of name attributes in a slot element, we've just unlocked some crazy smartness to our static slot element. Now it can render different content at specific points.

// child template: Post.js
<section>
  <header><slot name="header"></slot></header>
  <div><slot name="body"></slot></div>
</section>

To add your custom header and body into Slot, wrap the slot content with <template v-slot:NAME>.
See the code below.

<Post>
  <template v-slot:header>How to drink water</template>
  <template v-slot:body>...</template>
</Post>

// compiles to
<section>
  <header>How to drink water</header>
  <div>...</div>
</section>

Super-power IV: Pass props from Slot child to the parent component, and vice-versa

<section>
  <header><slot name="header" :text="greet"></slot></header>
  <div><slot name="body"></slot></div>
</section>

<Post>
  <template v-slot:header = "props"> {{props.text}} </template>
  <template v-slot:body>...</template>
</Post>

A big thank you for reading thus far. Since you did, you deserve a gift: take this joke ๐Ÿ˜†

One day you'll wake up and realize your favorite song from high school is 10 years old. And your co-worker saying they weren't born yet ๐Ÿคฃ.
Joke courtesy of @TheJackForge

ย