DEV Community

Carsten Behrens
Carsten Behrens

Posted on • Originally published at fiddit.io

Scoped Slots in Vue for Dummies

What are scoped slots

To easily understand scoped slots, it is helpful to revisit the concept of regular slots.

Slots allow us to provide markup to a child component, this markup then gets rendered inside the child component.

E.g.:

<template>                                                                                          
  <child-component>                                                                                 
    This will get rendered inside the slot inside the child component -                             
    it is called the slot content.                                                                  
  </child-component>                                                                                
</template>                                                                                         

<script>                                                                                            
import ChildComponent from "./components/ChildComponent.vue";                                       

export default {                                                                                    
  name: 'App',                                                                                      
  components: {                                                                                     
    ChildComponent                                                                                  
  }                                                                                                 
}                                                                                                   
</script>                                                                                           
Enter fullscreen mode Exit fullscreen mode

So what are scoped slots?

Scoped slots are exactly like regular slots, with the difference that we pass data from the child component to the parent component. This data can then be used inside the slot content.

How to use scoped slots in Vue 2

The child component:

<template>                                                                                          
  <div>                                                                                             
    <slot v-bind:example="example">                                                                 
    </slot>                                                                                         
  </div>                                                                                            
</template>                                                                                         

<script>                                                                                            

export default {                                                                                    
  name: 'ChildComponent',                                                                           
  data() {                                                                                          
    return {                                                                                        
      example: 'just some data...'                                                                  
    }                                                                                               
  }                                                                                                 
}                                                                                                   
</script>                                                                                           
Enter fullscreen mode Exit fullscreen mode

How the data gets used inside the parent:

<template>                                                                                          
  <child-component>                                                                                 
    <template v-slot:default="slotProps">                                                           
      Now we can use the data from the child component here: {{ slotProps.example }}                
    </template>                                                                                     
  </child-component>                                                                                
</template>                                                                                         

<script>                                                                                            
import ChildComponent from "./components/ChildComponent.vue";                                       

export default {                                                                                    
  name: 'App',                                                                                      
  components: {                                                                                     
    ChildComponent                                                                                  
  }                                                                                                 
}                                                                                                   
</script>                                                                                           
Enter fullscreen mode Exit fullscreen mode

You can find the full code for this example here.

How to use scoped slots in Vue 3

The child component:

<template>                                                                                          
  <slot :example="example"></slot>                                                                  
</template>                                                                                         

<script setup>                                                                                      
import { ref } from 'vue'                                                                           

const example = ref('just some data')                                                               
</script>                                                                                           
Enter fullscreen mode Exit fullscreen mode

How the data gets used inside the parent:

<template>                                                                                          
  <child-component v-slot="slotProps">                                                              
    Now we can use the data from the child component here: {{ slotProps.example }}                  
  </child-component>                                                                                
</template>                                                                                         

<script setup>                                                                                      
import ChildComponent from './components/ChildComponent.vue'                                        
</script>                                                                                           
Enter fullscreen mode Exit fullscreen mode

You can find the full code for this example here.

Why use scoped slots

So why would we want to use scoped slots in vue?

We use scoped slots to give more responsibility to the consumer of our component this allows our components to be more reusable!

Example: Scroll Progress Bar

To see a real-life example of how this amazing Vue feature can be used, take a look at this library here.

Using scoped slots, we give the user full control over how the component should look. The only downside to this is that we also expose more complexity to the user of our library/component.

Top comments (0)