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;
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;
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:
Dynamic slot name:
-
Currently the slot names we use are all fixed;
-
For example
v-slot:left
,v-slot:center
etc.; -
We can
v-slot:[dynamicSlotName]
dynamically bind a name by means of;
Abbreviation when using named slots:
-
Like
v-on
andv-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;
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 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>
: