Know the component weapon in Vue - slot Slot - case introduction

1. Use of slots

1.1. Understanding slots

In development, we often encapsulate reusable components one by one:

  • Earlier, we will pass some data to the component through props, and let the component display it;

  • But in order to make this component more versatile, we cannot limit the content in the component to fixed div, span, etc. elements;

  • For example, in some cases, we use components to display a button, and in some cases, we use components to display a picture;

  • We should allow users to decide what content is stored in a certain area;

Take a chestnut: If we customize a general navigation component - NavBar

  • This component is divided into three areas: left-middle-right, and the content of each area is not fixed;

  • The left area may display a menu icon, or a back button, or nothing;

  • The middle area may display a search box, a list, a title, etc.;

  • The right side may be a text, or an icon, or nothing;

JD Navigation

At this time we can define the slot slot:

  • The process of using slots is actually to extract the commonality and retain the differences;

  • We will still encapsulate the common elements and content in the component;

  • At the same time, slots will be used as placeholders for different elements, allowing the outside world to decide what elements to display;

How to use slots?

  • In Vue,  <slot> the element is used as the outlet to carry the distributed content;

  • In packaged components, <slot>a slot can be opened for packaged components by using a special element;

  • What the slot inserts depends on how the parent component uses it;

1.2. Use of slots

1.2.1. Basic use of slots

Our component MySlotCpn.vue:

  • There is a slot in this component, we can put the content that needs to be displayed in the slot;

<template>
  <div>
    <h2>MySlotCpn开始</h2>
    <slot></slot>
    <h2>MySlotCpn结尾</h2>
  </div>
</template>

We use them in App.vue:

  • We can insert ordinary content, html elements, and component elements, all of which are possible;

<template>
  <div>
    <my-slot-cpn>
      <!-- 1.普通的内容 -->
      Hello World
      <!-- 2.html元素 -->
      <button>我是按钮</button>
      <!-- 3.组件元素 -->
      <my-button></my-button>
    </my-slot-cpn>
  </div>
</template>

1.2.2. Default contents of slots

Sometimes we hope that when using a slot, if there is no corresponding content inserted, then we need to display a default content:

  • Of course, this default content will only be displayed when no inserted content is provided;

The default value of the slot
The default value of the slot

1.2.3. Use of named slots

Let's test a knowledge point first: If a component contains multiple slots, what is the effect when we insert multiple content?

  • We will find that by default, each slot will get the content we inserted to display;

The effect of multiple slots

In fact, the effect we want to achieve is the display corresponding to the slot. At this time, we can use  具名插槽:

  • As the name implies, the named slot is to give the slot a name, <slot> and the element has a special attribute: name;

  • A slot without a name will have an implicit name  default;

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

<template> We can use  v-slot a directive on an element and  v-slot provide its name as an argument when providing content to a named slot  :

<template>
  <div>
    <nav-bar>
      <template v-slot:left>
        <button>左边按钮</button>
      </template>
      <template v-slot:center>
        <h2>中间标题</h2>
      </template>
      <template v-slot:right>
        <i>右边i元素</i>
      </template>
    </nav-bar>
  </div>
</template>

The slot usage process is as follows:

Use of named slots

Dynamic slot name:

  • Currently the slot names we use are all fixed;

  • For example  v-slot:left, v-slot:centeretc.;

  • We can  v-slot:[dynamicSlotName]dynamically bind a name by means of;

dynamic slot name

Abbreviation when using named slots:

  • Like  v-on and  v-bind , v-slot there are also abbreviations;

  • That is, replace all content ( ) before the parameter v-slot:with characters  #;

<template>
  <div>
    <nav-bar>
      <template #left>
        <button>左边按钮</button>
      </template>
      <template #center>
        <h2>中间标题</h2>
      </template>
      <template #right>
        <i>右边i元素</i>
      </template>
    </nav-bar>
  </div>
</template>

2. 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 inside a child template is compiled in the child scope;

How to understand this sentence? Let's look at a case:

  • In our case, ChildCpn can naturally ask itself the title content in the scope;

  • But in the App, the content in ChildCpn cannot be accessed, because they are cross-scope access;

Case Scope Access

2.2. Scoped slots

But sometimes it is very important that we want the slot to be able to access the content in the child component:

  • We use slots when a component is used to render an array element, and we want the content of each item not displayed in the slot;

  • This Vue provides us with scoped slots;

Let's look at the following case:

  • 1. Define the data in App.vue

  • 2. Passed to the ShowNames component

  • 3. Traverse the names data in the ShowNames component

  • 4. Define the prop of the slot

  • 5. Obtain the props of the slot through v-slot:default

  • 6. Use item and index in slotProps

The case for 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>

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: {
      names: {
        type: Array,
        default: () => []
      }
    }
  }
</script>

2.3. Exclusive default slot

If our slot is the default slot default, it  v-slot:default="slotProps"can be abbreviated as v-slot="slotProps":

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

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

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

However, if we have default slots and named slots, then follow the full template to write.

Default and named slots

Whenever multiple slots appear, always use the full-based syntax for all slots  <template> :

Complete template writing

Guess you like

Origin blog.csdn.net/JackieDYH/article/details/124481953