The Secret Power of Renderless Components

Ryan Durham

Senior Engineer @ Phylos
Owner @ Stage Right Labs

ryan at stagerightlabs dot com

stagerightlabs

Scoped Slots + Renderless Components =

Game Changer

What is a "scoped" slot?

Slots

Slots allow parent components to inject
content into child components.

"Default" Slot


// App.vue - Parent

// MyComponent.vue - Child

"Default" Slot - Result


Child Heading

Hello World!

What if you want to inject into multiple locations?

"Named" Slots

You can have as many named slots as you want,
in addition to the default slot.

Named Slots


// App.vue - Parent

// MyComponent.vue - Child

Named Slots - Result


Parent Heading

Hello World!

What if you want to refer to child component data?

Scoped Slots

"Scoped" slots have access to child component data.

Scoped Slot Example


// App.vue - Parent



              

// MyComponent.vue - Child



              

Slot props can be destructured


// App.vue - Parent

        

This also works with default slots


// App.vue

        

Important Note

The slot API we are looking at is from Vue 2.6+. If you are using an earlier version of Vue things will work exactly the same, but the API is slightly different.

What is a renderless component?

Standard Vue Component

          
// MyComponent.vue





          
        

Alternative: Inline Template

          



          
        

Alternative: Render Function

          



          
        

createElement() generates virtual nodes that will be inserted into Vue's virtual DOM.

createElement()

          
// @returns {VNode}
createElement(
  'div', // String or function that returns a tag name

  // {String | Array}
  // Children VNodes, built using `createElement()`,
  // or using strings to get 'text VNodes'. Optional.
  [
    'Some text comes first.',
    createElement('h1', 'A headline'),
    createElement(MyComponent, {
      props: {
        someProp: 'foobar'
      }
    })
  ]
)
          
        
https://vuejs.org/v2/guide/render-function.html
createElement() is sometimes called h()

Vue Template Explorer

Use the Template Explorer to see how render functions are generated by Vue behind the scenes:

https://template-explorer.vuejs.org/

What happens when we combine render
functions and scoped slots?

Render slot content


// MyComponent.vue

        

This is now a "renderless" component.

Usage


// App.vue

        

"Renderless" components allow us to inject functionality that does not rely on specific UI/UX.

Demo

Shift + Click Range Selection

https://codesandbox.io/s/xoy96vw0o

More about slots:

https://vuejs.org/v2/guide/components-slots.html

Advanced Vue Component Design

by Adam Wathan

Thank you!

ryan at stagerightlabs dot com

stagerightlabs

Stage Right Labs Logo