The third component of the three API: slot
<slot>
labelv-slot
instruction- Ordinary Slot
- It has a default value of slots
- Named Slot
- Scope slot
v-slot
Is Vue 2.6.0
a new grammar instruction is introduced with the aim of reunification before slot / slot-scope
usage. Unified command syntax is more concise and easier to understand.
Before explain prop
achieve data transfer assembly downward, and event
the v-on / $emit
enables data transfer assembly upwardly. This section v-slot
directive implementing component content customization features.
A simple example of a custom button component:
<div id="app">
<p>this is example for slot</p>
<custom-button></custom-button>
</div
const customButton = Vue.extend({
template: `<button>提交</button>`,
})
const vm = new Vue({
el: "#app",
components: {
customButton,
},
})
At this time, this custom button is bound to be a submit button because we wrote the text on the button fixed dead "Submit." If we need to use the buttons according to different scenarios, showing different text, such as may be submitted, delete, confirm, or return. In this case we can use components <slot>
tag, which corresponds to the contents inside the placeholder assembly.
Ordinary Slot
The above example we only need to define the component in place with the button text <slot><slot>
labels to representatives
const customButton = Vue.extend({
template: `<button>
<slot></slot>
</button>`,
})
Then offer to provide content when you can use the component
<div id="app">
<p>this is example for slot</p>
<custom-button>提交</custom-button>
<custom-button>删除</custom-button>
<custom-button>返回</custom-button>
</div
At this point on the custom button to display the complete text of what is determined by the component use, rather than determine when the component definition.
It has a default value of slots
Demand upgrade, we hope that when the component is not written in the text when you call, the default display "OK." In this case the component may be <slot>
a definition of the label text content, it will act as the default content display component.
const customButton = Vue.extend({
template: `<button>
<slot>确认</slot>
</button>`,
})
div id="app">
<p>this is example for slot</p>
<!-- 有输入内容显示输入的内容:提交 -->
<custom-button>提交</custom-button>
<!-- 没有输入内容时默认显示定义时文字:确认 -->
<custom-button></custom-button>
</div
Named Slot
The above only provides custom button assembly occupying a slot, but the need to abstract the content of the component kinds, such as a paragraph content component, including custom heading, paragraph text, the writing time of three parts. This component was analyzed by at least three parts, and the contents of three parts only know what the input only when the component uses.
So when we define the component that provides three occupying slots, one for the title, a display for time, other content as text
const customSection = Vue.extend({
template: `<section>
<header>
<slot name="title"></slot>
</header>
<main>
<slot></slot>
</main>
<footer>
<slot name="time"></slot>
<footer>
</section>`,
})
<custom-section>
<template v-slot:title>段落标题</template>
<template>这是段落正文部分,内容很长,这里就省略了......</template>
<template v-slot:time>2019-5-26</template>
</custom-section>
The syntax is simple:
- When the component definition:
<slot>
tag when a specifiedname
attribute value to - When using the assembly,
<template>
with the labelv-slot
instruction parameter indicates the specific names, which represents the current template placeholders for contentslot
to.
When the contents have multiple named slots, slot when written component calls need
<template>
labels wrap
Unnamed default slot, there is a name that comes insidedefault
<!-- 定义时 -->
<main><slot></slot></main>
<main><slot name="defalut"></slot></main>
<!-- 使用时 -->
<template>这是段落正文部分,内容很长,这里就省略了......</template>
<template v-slot:default>这是段落正文部分,内容很长,这里就省略了......</template>
Dynamic selection of slots
can define multiple sets of slots, external reference display decide which named slot call, equivalent to a switch statement based on conditions in the sub-assembly.
<div id="app">
<button @click="changeSlot">点击切换slot</button>
<custom-section>
<template v-slot:[variable]>改变了插槽</template>
</custom-section>
</div>
const customSection = Vue.extend({
template: `<article>
<slot name="js">this is content for js</slot>
<slot name="html">this is content for html</slot>
<slot name="css">this is content for css</slot>
</article>`,
})
const vm = new Vue({
el: "#app",
components: {
customSection
},
data: {
index: 0,
arr: ['html', 'css', 'js'],
variable: 'html'
},
methods: {
changeSlot() {
this.variable = this.arr[++this.index % 3]
}
}
})
Scope slot
Here's the concept of a domain, there is a saying in the official document:
Parent template of all content is the role of the parent in the domain compiled; sub-template of all the contents are compiled in the sub-domain action.
In simple terms:
Slot although the content component tag quilt wrapped, but in fact, like slot subassembly labels attribute in the parent template scope. Data can be referenced within the scope of the direct parent component. But it can not directly reference the data sub-template scope.
const customSection = Vue.extend({
template: `<section>
<header>
<slot name="title"></slot>
</header>
<main>
<slot></slot>
</main>
<footer>
<slot name="time"></slot>
<footer>
</section>`,
data:() => {
return {
innerTitle: '写在子级的标题'
}
}
})
const vm = new Vue({
el: "#app",
data: {
outerTitle: '写在父级的标题'
},
components: {
customSection,
},
})
The above code, we are in the root element vm
defines the title outerTitle: '写在父级的标题'
, sub-assemblies also custom-section
defines the title innerTitle: '写在子级的标题'
.
<div id="app">
<p>这里可以直接引用父级标题:{{ outerTitle }}</p>
<custom-section>
<!-- 在插槽模板内也可以使用父级作用域内的数据的 -->
<template v-slot:title>{{ outerTitle }}</template>
<!-- <template v-slot:title>段落标题</template> -->
<template>这是段落正文部分,内容很长,这里就省略了......</template>
<template v-slot:time>2019-5-26</template>
</custom-section>
</div>
<div id="app">
<p>这里是肯定不可以直接引用子级标题:{{ innerTitle }}</p>
<custom-section>
<!-- 在插槽也不能直接引用子组件内的数据,控制台会报错!!! -->
<template v-slot:title>{{ innerTitle }}</template>
<!-- <template v-slot:title>段落标题</template> -->
<template>这是段落正文部分,内容很长,这里就省略了......</template>
<template v-slot:time>2019-5-26</template>
</custom-section>
</div>
But the content is a final slot in the sub-assembly, so often data is needed inside the subassembly to operate. In this case it is necessary to transfer the data within the sub-assembly upwardly defining the slot, the slot so that the call may be used.
const customSection = Vue.extend({
template: `<section>
<header>
// <slot name="title"></slot>
<slot name="title" :title="innerTitle"></slot>
</header>
<main>
<slot></slot>
</main>
<footer>
<slot name="time"></slot>
</footer>
</section>`,
data:() => {
return {
innerTitle: '写在子级的标题'
}
}
})
<div id="app">
<p>这里可以直接引用父级标题:{{ outerTitle }}</p>
<custom-section>
<!-- <template v-slot:title>段落标题</template> -->
<template v-slot:title="slotProp">{{ slotProp.title }}</template>
<template>这是段落正文部分,内容很长,这里就省略了......</template>
<template v-slot:time>2019-5-26</template>
</custom-section>
</div>
See when defining <slot>
provided with tag v-bind
values need to pass the binding subassembly
<slot name="title" :title="innerTitle"></slot>
When slot call, by v-slot
receiving a value after use.
<template v-slot:title="slotProp">{{ slotProp.title }}</template>
And the v-slot
value is taken over in the form of an object, the definition v-bind
can be bound to a plurality, in v-slot
the key-value to the reception, the use of the object dot call.
<slot name="title" :title="innerTitle" :author="author"></slot>
<template v-slot:title="slotProp">{{ slotProp.title + '-' + slotProp.author }}</template>
Slot prop deconstruction of
course, if you do not want to use objects RBI calls, you can also use the object syntax to call ES6 deconstruction.
<slot name="title" :title="innerTitle" :author="author"></slot>
<template v-slot:title="{ title, author }">{{ title + '-' + author }}</template>
Slot prop rename
If you pass up the prop may be variable with the same name as the parent scope references may be renamed when the deconstruction
<slot name="title" :title="innerTitle" :author="author"></slot>
<template v-slot:title="{ title, author:writer }">{{ title + '-' + writer }}</template>
The default value of prop slot
can also write a default content, avoid receiving the prop is undefined situation
<slot name="title" :title="innerTitle" :author="author"></slot>
<template v-slot:title="{ title, author='anonymity'}">{{ title + '-' + author }}</template>
Slot prop is a function of the parameters
in the official document explained, the inner workings of the slot is the slot include in your function parameters in a single pass, so the new syntax ES6 function parameters can be used, such as deconstruction, The default parameter values, etc.
function (slotProps) {}
function ({title, author}) {}
function ({title, author=anonymity}) {
// 插槽内容
}
v-slot
Shorthand#
with v-bind
abbreviated as :
, v-on
abbreviated as @
as v-slot
shorthand @
when the use of abbreviations #
must be followed by one slot name, as #
when binding a default slot, you need to write#default
// 可以
<template v-slot="slotProp"></template>
// 错误
<template #="slotProp"></template>
// 改成
<template #defalut="slotProp"></template>
When the exclusive default slot, v-slot can be bound label on the subassembly, template omitted
<div id="app">
<p>this is example for slot</p>
<custom-button v-slot={type}>{{ type ? '确定' : '删除'}}</custom-button>
<custom-button #default={type}>{{ !type ? '确定' : '删除'}}</custom-button>
</div
const customButton = Vue.extend({
template: `<button><slot :type="btnType"></slot></button>`,
data() => {
return {
btnType: 1, // 1 确定 0 删除
}
}
})
const vm = new Vue({
el: "#app",
components: {
customButton,
},
})
to sum up
v-slot:slotName="slotProp"
#:slotName="slotProp"