Scoped Slots in Vue for Dummies
Tags: vue, webdev, javascript
Published: 2022-05-02 18:54:52

## 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.:                                                                                               
                                                                                                    
```vue                                                                                              
<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>                                                                                           
```                                                                                                 
                                                                                                    
**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:                                                                                
                                                                                                    
```vue                                                                                              
<template>                                                                                          
  <div>                                                                                             
    <slot v-bind:example="example">                                                                 
    </slot>                                                                                         
  </div>                                                                                            
</template>                                                                                         
                                                                                                    
<script>                                                                                            
                                                                                                    
export default {                                                                                    
  name: 'ChildComponent',                                                                           
  data() {                                                                                          
    return {                                                                                        
      example: 'just some data...'                                                                  
    }                                                                                               
  }                                                                                                 
}                                                                                                   
</script>                                                                                           
```                                                                                                 
                                                                                                    
How the data gets used inside the parent:                                                           
                                                                                                    
```vue                                                                                              
<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>                                                                                           
```                                            

You can find the full code for this example [here](https://github.com/carstenbehrens/scoped-slots-v2).
                                                                                                    
## How to use scoped slots in Vue 3                                                                 
                                                                                                    
The child component:                                                                                
                                                                                                    
```vue                                                                                              
<template>                                                                                          
  <slot :example="example"></slot>                                                                  
</template>                                                                                         
                                                                                                    
<script setup>                                                                                      
import { ref } from 'vue'                                                                           
                                                                                                    
const example = ref('just some data')                                                               
</script>                                                                                           
```                                                                                                 
                                                                                                    
How the data gets used inside the parent:                                                           
                                                                                                    
```vue                                                                                              
<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>                                                                                           
```                                                                                                 
                                                                                                    
You can find the full code for this example [here](https://github.com/carstenbehrens/scoped-slots-v3).
                                                                                                    
## 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](https://github.com/carstenbehrens/reusable-vue-scroll-progress-bar).
                                                                                                    
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.