Detailed explanation of vue slot

Posted by skippence on Thu, 03 Mar 2022 23:26:10 +0100

Detailed explanation of vue slot

Recently, I was asked if I knew about vue slots. When I thought about it, I found that this thing seems to be rarely used. So I sorted out some usage of slot.

slot (the parent component inserts content at the child component)

vue implements a set of API s for content distribution, and takes elements as the exit to host the distribution content, which is described in the vue document. Specifically, a slot is a 'space' that allows you to add content to a component. for instance:

//Subcomponent: (assumed name: ebutton)
<template>
  <div class= 'button'>
      <button>  </button>
  </div>
</template>
//Parent component: (reference child component ebutton)
<template>
  <div class= 'app'>
     <ebutton> </ebutton>
  </div>
</template>

We know that if you directly want to add content to the in the parent component, it will not be rendered on the page. So how can we make the added content be displayed? Just add a slot in the sub component.

//Subcomponent: (assumed name: ebutton)
<template>
  <div class= 'button'>
      <button></button>
      <slot></slot>       //Slots can be placed anywhere. (this position is the display position of the added content of the parent component)
  </div> 
</template>

Child components can add slot s at any location, which is the display location of the added content of the parent component.

Compile scope (parent component inserts data at child component)
As we have learned above, a slot is actually a 'space' that allows us to add content to the child component in the parent component. We can add any data value in the parent component, for example:

//Parent component: (reference child component ebutton)
<template>
  <div class= 'app'>
     <ebutton> {{ parent }}</ebutton>
  </div>
</template>

new Vue({
  el:'.app',
  data:{
    parent:'Parent component'
  }
})

The syntax of using data has not changed at all, but can we directly use the data in the sub component? Obviously not!!

// Subcomponent: (assumed name: ebutton)
<template>
  <div class= 'button'>
      <button> </button>
       <slot></slot>
  </div>
</template>

new Vue({
  el:'.button',
  data:{
    child:'Subcomponents'
  }
})
// Parent component: (reference child component ebutton)
<template>
  <div class= 'app'>
     <ebutton> {{ child }}</ebutton>
  </div>
</template>

It is not allowed to directly transfer data into sub components. Because: all contents in the parent template are compiled in the parent scope; All contents in the sub template are compiled in the sub scope.

Backup content (sub component setting default value)
The so-called back content is actually the default value of slot. Sometimes I don't add content in the parent component, then slot will display the default value, such as:

//Subcomponent: (assumed name: ebutton)
<template>
  <div class= 'button'>
      <button>  </button>
      <slot> This is the default </slot>
  </div>
</template>

Named slot (multiple corresponding inserts of sub components)

Sometimes, there may be more than one slot in the child component, so how can we insert the corresponding content in the parent component exactly at the desired position? Just give the slot a name, that is, add the name attribute.

//Subcomponent: (assumed name: ebutton)
<template>
  <div class= 'button'>
      <button>  </button>
      <slot name= 'one'> This is the default value of 1</slot>
      <slot name='two'> This is the default value of 2 </slot>
      <slot name='three'> This is the default value of 3 </slot>
  </div>
</template>

The parent component adds content through V-slot: Name:

//Parent component: (reference child component ebutton)
<template>
  <div class= 'app'>
     <ebutton> 
        <template v-slot:one> This is inserted into one Contents of slot </template>
        <template v-slot:two> This is inserted into two Contents of slot </template>
        <template v-slot:three> This is inserted into three Contents of slot </template>
     </ebutton>
  </div>
</template>

Of course vue, for convenience, when writing the form of v-slot:one, it can be abbreviated as #one

Scope slot (parent component uses child component data at child component)

Through slot, we can add content for child components in the parent component. By naming the slot, we can add content in more than one location. However, the data we add is in the parent component. As mentioned above, we can't directly use the data in the sub component, but do we have other methods to use the data of the sub component? In fact, we can also use v-slot:

//Subcomponent: (assumed name: ebutton)
<template>
  <div class= 'button'>
      <button>  </button>
      <slot name= 'one' :value1='child1'> This is the default value of 1</slot>    //Bind the data of child1
      <slot :value2='child2'> This is the default value of 2 </slot>  //Bind the data of child2. I don't name slot here
  </div>           
</template>
//Parent component: (reference child component ebutton)
new Vue({
  el:'.button',
  data:{
    child1:'Data 1',
    child2:'Data 2'
  }
})
<template>
  <div class= 'app'>
     <ebutton> 
        <template v-slot:one = 'slotone'>  
           {{ slotone.value1 }}    // Assign the value1 value of the sub component to slot one through the syntax of v-slot 
        </template>
        <template v-slot:default = 'slottwo'> 
           {{ slottwo.value2 }}  // The same as above. Since the sub component does not name the slot, the default value is default
        </template>
     </ebutton>
  </div>
</template>

In summary:

  • First, dynamically bind a value on the slot of the sub component (: key = 'value')
  • Then, the parent component assigns this value to values through V-slot: name = 'values'
  • Finally, the data is obtained through {{values.key}}