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 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>
Copy the code
When feeding content to a named slot, we can use the V-slot directive on a
element and supply its name as an argument to the v-slot:
<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 as
v-slot:left
,v-slot:center
And so on; - We can get through
v-slot:[dynamicSlotName]
Way to dynamically bind a name;
Abbreviations used for named slots:
- with
v-on
和v-bind
The same,v-slot
There 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
based syntax for all slots:
The full template method