One. The use of slots

1.1. Learn about slots and slots

In development, we often encapsulate reusable components:

  • We’re going to pass some data to the component via props so that the component can present it.
  • But to make this component more universal, we can’t limit the content of the component to fixed elements like divs, spans, and so on;
  • In one case we’re using a component and we want it to display a button, in another case we’re using a component and we want it to display an image;
  • We should give users the ability to decide what to store in an area;

For example: suppose we customize a generic navigation component – NavBar

  • The component is divided into three areas: left-middle-right. The contents of each area are not fixed.
  • The left area might show a menu icon, it might show a back button, it might show nothing;
  • The middle area might display a search box, a list, a title, and so on;
  • It could be a text, it could be an icon, it could be nothing;

Jingdong navigation

At this point we can define the slot:

  • The process of using slots is to extract commonness and retain differences;
  • We’ll still encapsulate common elements and content within components;
  • Slots are used as placeholders for different elements, allowing the external world to decide what elements to display.

How do you use slot?

  • The Vue will<slot>Element as an outlet to carry distribution content;
  • In encapsulated components, use special elements<slot>You can open a slot for encapsulated components;
  • What the slot inserts depends on how the parent uses it;

1.2. Use of slots

1.2.1. Basic use of slots

We have a component myslotcpn.vue:

  • This component has a slot where we can put what we want to display;
<template> <div> <h2>MySlotCpn start </h2> <slot></slot> <h2>MySlotCpn end </h2> </div> </template>Copy the code

We use them in app.vue:

  • We can insert normal content, HTML elements, component elements, whatever;
<template> <div> <my-slot-cpn> <! -- 1. Common content --> Hello World <! -- 2. HTML elements --> <button> </button> <! - 3. The component element - > < my - button > < / my - button > < / my - slot - CPN > < / div > < / template >Copy the code

1.2.2. Default contents of slots

Sometimes we want to display a default content if no corresponding content is inserted when using a slot:

  • Of course, the default content will only be displayed if no content is provided for insertion;

The default value of the slot

1.2.3. Use of named slots

Let’s start with a test: if a component has multiple slots, what happens when we insert multiple content?

  • We’ll see that by default each slot gets what we insert to display;

Effect of multiple slots

In fact, the effect we want to achieve is that the slot corresponds to the display, in which case we can use named slots:

  • A named slot, as the name suggests, gives a slot a name,<slot>The element has a special attribute: name;
  • A slot without a name will have an implied namedefault;
<template>
    <div class="nav-bar">
        <div class="left">
        <slot></slot>
    </div>
    <div class="center">
        <slot></slot>
    </div>
    <div class="right">
        <slot></slot>
    </div>
    </div>
</template>
Copy the code

When feeding content to a named slot, we can use the V-slot directive on a

<template> <div> <nav-bar> <template V-slot :left> <button> </button> </template> <template V-slot :center> <h2> Middle title </h2> </template> <template V-slot :right> < I > Right I element </ I > </template> </nav-bar> </div> </template>Copy the code

The procedure for using a slot is as follows:

The use of named slots

Dynamic slot name:

  • Currently we use fixed slot names;
  • Such asv-slot:left,v-slot:centerAnd so on;
  • We can get throughv-slot:[dynamicSlotName]Way to dynamically bind a name;

Abbreviations used for named slots:

  • withv-on 和 v-bindThe same,v-slotThere are also abbreviations;
  • That is, everything before the parameter (v-slot:) is replaced with a character#;
<template> <div> <nav-bar> <template #left> </button> </template> <template #center> </template> <template #right> < I > </ I > </template> </nav-bar> </div> </template>Copy the code

Two. Scope slot

2.1. Render scope

In Vue there is the concept of render scope:

  • Everything in the parent template is compiled in the parent scope;
  • Everything in a subtemplate is compiled in a subscope;

How to understand this sentence? Let’s take a look at an example:

  • In our case ChildCpn is naturally able to ask itself about the title content of the scope;
  • In the App, however, you cannot access the contents of ChildCpn because they are cross-scoped;

Case scoped access:

2.2. Scope slot

But sometimes it’s important that we want the slot to have access to the content in the child component:

  • When a component is used to render an array element, we use a slot and expect that the slot does not display the contents of each item;
  • The Vue gives us scope slots;

Let’s take a look at an example:

  • 1. Define data in app.vue
  • 2. Send the file to ShowNames
  • 3. The ShowNames component traverses names data
  • 4. Define a prop for the slot
  • 5. Obtain the props of the slot in v-slot:default mode
  • 6. Use item and index in slotProps

Examples of scoped slots:

The specific code is as follows:

App. Vue code:

<template>
  <div>
    <show-names :names="names">
      <template v-slot:default="slotProps">
        <span>{{slotProps.item}}-{{slotProps.index}}</span>
      </template>
    </show-names>
  </div>
</template>

<script>
  import ShowNames from './ShowNames.vue';

  export default {
    components: {
      ShowNames,
    },
    data() {
      return {
        names: ["why", "kobe", "james", "curry"]
      }
    }
  }
</script>
Copy the code

ShowNames. Vue code:

<template> <div> <template v-for="(item, index) in names" :key="item"> <! -- prop --> <slot :item="item" :index="index"></slot> </template> </div> </template> <script> export default {props: props: props { names: { type: Array, default: () => [] } } } </script>Copy the code

2.3. Exclusive default slot

If the slot is the default slot, then v-slot:default=”slotProps” can be shortened to v-slot=”slotProps” :

<show-names :names="names">
  <template v-slot="slotProps">
		<span>{{slotProps.item}}-{{slotProps.index}}</span>
  </template>
</show-names>
Copy the code

And if our slot only has the default slot, the component tag can be used as a template for the slot, so we can use v-slot directly on the component:

<show-names :names="names" v-slot="slotProps">
  <span>{{slotProps.item}}-{{slotProps.index}}</span>
</show-names>
Copy the code

However, if we have a default slot and a named slot, we write the full template.

Default slot and named slot:

Whenever multiple slots are present, always use the full

The full template method

Thank you