Slots for vue2 and vue3

Posted by billynastie on Mon, 27 Dec 2021 04:15:18 +0100

Preface: the use of slots is actually very simple. You only need to understand two points:

1. Slots are used in sub assemblies.

2. Slots are used to display the template data of child components in the parent component normally

vue2. Slot for 0

Without much to say, let's go directly to the case:

<div id="app">
    <div class="father">
        <h3>This is the parent component</h3>
        <child>
           <span>I am the content inserted in the slot</span>
        </child>
    </div>
</div>
<template id="child">
    <div class="child">
        <h3>Here are the subcomponents</h3>
        <slot></slot>
    </div>
</template>
<script>
    var vm = new Vue({
        el: '#app',
        data: {},
        components: {
            child: {
                template: '#child'
            }
        }

    });

</script>

The effect shown by the above code is that you will find that < H3 > here is a sub component < / H3 >, and there will be an additional line of < span > I am the content inserted in the slot</span>
If you don't write < slot > < / slot > in the child component, you will find that no matter how many tags you write in the parent component, they will not be rendered into the child tag.

< font color = Red > this is the legendary slot. How about it? Is it simple</ font>

The above case is anonymous slot. Let's take a look at "named slot"

<div id="app">
    <div class="father">
        <h3>This is the parent component</h3>
        <child>
            <span slot="demo1">Menu 1</span>
            <span>Menu 2</span>
            <span slot="demo3">Menu 3</span>
        </child>
    </div>
</div>
<template id="child">
    <div class="child">
        <h3>Here are the subcomponents</h3>
        <slot></slot>
        <slot name="demo3"><slot>
    </div>
</template>
<script>
    var vm = new Vue({
        el: '#app',
        data: {},
        components: {
            child: {
                template: '#child'
            }
        }
    });
</script>

A named slot is actually an attribute with slot = 'custom name' added to the parent component,
Then add < name = 'custom name' in < slot > < slot > in the sub component
If the slot attribute is not added to some of the parent components, this is the default slot. The < slot > < / slot > in the child components is directly the default slot of the parent components used

Scope slot

Everything in the parent component template will be compiled in the parent scope; Everything in the subcomponent template is compiled within the child scope.
However, we can use the slot scope feature in the parent component to get data from the child component
The premise is that you need to use: data=data in the subcomponent to pass the data of data first

<div id="app">
    <div class="father">
        <h3>This is the parent component</h3>
        <child>
            <div slot-scope="user">
                {{user.data}}
            </div>
        </child>
    </div>
</div>
<script>
    Vue.component('child', {
        template:'' +
            '<div class="child">\n' +
            '    <h3>Here are the subcomponents</h3>\n' +
            '    <slot  :data="data"></slot>\n' +
            '  </div>',
        data: function () {
            return {
                data: ['zhangsan', 'lisi', 'wanwu', 'zhaoliu', 'tianqi', 'xiaoba']
            }
        }
    });
    var vm = new Vue({
        el: '#app',
    });
</script>

The results displayed on the page are as follows:

This is the parent component

Here are the subcomponents

['zhangsan', 'lisi', 'wanwu', 'zhaoliu', 'tianqi', 'xiaoba']

vue3. Use of slots in 0

Anonymous slot usage remains unchanged

Let's look at the writing of named slots

// Subcomponents
<div class="hello">
    I am an encapsulated component
     <slot name="num"></slot>
  </div>
  
  
// Parent component
<HelloWorld v-model="masg" v-slot:num>
    <div>I inserted the slot</div>
</HelloWorld>

// Another way to write a parent component
<HelloWorld v-model="masg">
    <template v-slot:num>
         <div>I inserted the slot</div>
    </template>
</HelloWorld>

Vue3 (actually starting from 2.6) introduces a new instruction v-slot to represent named slots and default slots.
In V2 After 5, the slot scope was shielded,
The introduction of v-slot makes its slot more directive.

Let's take a look at the usage of the scope slot

// Subcomponents
<div class="hello">
    I am an encapsulated component
     <slot :num="num"></slot>
</div>

<script>
import { ref } from 'vue';
export default {
  name: 'HelloWorld',
  props: {
    // msg: String,
    modelValue: String
  },
 setup(prop,context){
   const num = ref(10);
   return { num }
 }
}
</script>

// Parent component
<HelloWorld>
  <template v-slot="{num}">
     <div>{{num}}</div>
  </template>
</HelloWorld>

// You can also change it to the following
<HelloWorld v-slot="{num}">
   <div>{{num}}</div>
</HelloWorld>


and v-bind and v-on Similarly, abbreviations only take effect when parameters exist, which means v-slot Cannot be used without parameters#=,For the default slot, you can use#default instead of v-slot


// We wrote above that named slots can be written like this

<HelloWorld v-model="masg">
    <template #num>
         <div>I inserted the slot</div>
    </template>
</HelloWorld>

// Or, for example, the scope slot above can also be written in the following way

<HelloWorld>
  <template #default="{num}">
     <div>{{num}}</div>
  </template>
</HelloWorld>

Topics: Javascript ECMAScript Vue Vue.js