vue learning - slot 2

Almost understood

You can look at the previous article and this one

Reprinted from: https://zhuanlan.zhihu.com/p/114502325?from_voters_page=true

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 sub component < slot > < / slot >)

vue implements a set of API s for content distribution, using the < slot > element 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:

//Sub components: (The assumed name is: 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 < ebutton > < / ebutton > 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.

//Sub components: (The assumed name is: ebutton)
<template>
  <div class= 'button'>
      <button></button>
      <slot></slot>       //slot 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.

Compilation scope (the parent component inserts data at the sub component < slot > < / slot >)

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!!

// Sub components: (The assumed name is: 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 < slot > < / slot > set 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:

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

Named slot (multiple < slot > < / slot > < slot > < / slot > 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.

//Sub components: (The assumed name is: 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 sub component data at sub component < slot > < / slot >)

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 1 < / slot > / / bind Child1 data
      < slot: Value2 ='child2 '> this is the default value 2 < / slot > / / bind the data of child2. I don't name slot here
  </div>           
</template>

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

        // adopt v-slot The syntax of will be the slot one Value assigned to slotonevalue 
        <template v-slot:one = 'slotonevalue'>  
           {{ slotonevalue.value1 }}
        </template>

        // Same as above, because the sub components are not given slot Name, the default value is default
        <template v-slot:default = 'slottwovalue'> 
           {{ slottwovalue.value2 }}
        </template>

     </ebutton>
  </div>
</template>

In summary:

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

Keywords: Front-end

Added by lunarul on Thu, 27 Jan 2022 10:44:03 +0200