文章目录
-
-
-
- 默认slot
- 具名slot
- 作用域slot
- 作用域slot应用于组件复用
-
-
默认slot
<body><div id="root"><save-button></save-button></div>
</body>
import Vue from "vue";Vue.component("submit-button",{
template:'<div>\<button>\<slot>Submit</slot>\</button>\</div>'
});
Vue.component("save-button",{
template:'<submit-button>Save</submit-button>'
})
// Vue.component("save-button",{
// template:'<submit-button></submit-button>'
// })
const vm = new Vue({
el:"#root"
});
具名slot
- H5新元素
header
nav
article
section
aside
footer
<body><div id="root"><header>here is header</header><nav>here is nav</nav><div><article><section>here is article > section</section></article><aside>here is aside</aside></div><footer>here is footer</footer></div>
</body>
- 具名slot
<template v-slot:对应的slot名称> </template>
<slot name="slot名称"></slot>
<template v-slot=""></template>
的子内容将插入到<slot name=""><slot>
所在位置
<body><div id="root"><base-layout><template v-slot:header><h4>here is header</h4></template><template v-slot:default><p>here is the section</p><p>here is the content of the section</p></template><template v-slot:footer><p>here is footer</p></template></base-layout></div>
</body>
import Vue from "vue";Vue.component("base-layout",{
template:'<div class="container">\<header>\<slot name="header"></slot>\</header>\<section>\<slot name="default"></slot>\</section>\<footer>\<slot name="footer"></slot>\</footer>\</div>'
})const vm = new Vue({
el:"#root"
});
- 具名slot的简写
- 将
v-slot:header
简写成#header
- 将
v-slot:default
简写成#default
- 将
v-slot:footer
简写成#footer
- 将
<body><div id="root"><base-layout><template #header><h4>here is header</h4></template><template #default><p>here is the section</p><p>here is the content of the section</p></template><template #footer><p>here is footer</p></template></base-layout></div>
</body>
<body><div id="root"><base-layout><template #header><h4>here is header</h4></template><p>here is the section</p><p>here is the content of the section</p><template #footer><p>here is footer</p></template></base-layout></div>
</body>
import Vue from "vue";Vue.component("base-layout",{
template:'<div class="container">\<header>\<slot name="header"></slot>\</header>\<section>\<slot></slot>\</section>\<footer>\<slot name="footer"></slot>\</footer>\</div>'
})const vm = new Vue({
el:"#root"
});
作用域slot
<body><div id="root"><current-user></current-user></div>
</body>
import Vue from "vue";Vue.component("current-user",{
template:'<div>\<slot>{
{user.lastname}}</slot>\</div>',data:function(){
return {
user:{
firstname:"Steve",lastname:"Jobs",fullname:"Steve Jobs"}}}
})
const vm = new Vue({
el:"#root"
});
但是,如果像下面这样
<body><div id="root"><current-user>{
{user.firstname}}</current-user></div>
</body>
则会迎来“一丈红”。
这是因为user
是组件current-user
作用域下的变量,而父级访问不了组件current-user
的作用域。
不过,作用域slot可以解决上面的问题。
- 组件
current-user
使用v-bind:user="user"
将自身作用域下的user
传递出来 - 父级使用
v-slot:default="slotProps"
通过slotProp.user
接收过来
<body><div id="root"><current-user v-slot:default="slotProps">{
{slotProps.user.firstname}}</current-user></div>
</body>
import Vue from "vue";Vue.component("current-user",{
template:'<div>\<slot v-bind:user="user">{
{user.lastname}}</slot>\</div>',data:function(){
return {
user:{
firstname:"Steve",lastname:"Jobs",fullname:"Steve Jobs"}}}
})
const vm = new Vue({
el:"#root"
});
下面是作用域slot的几种写法。
- 第一种,
v-slot:default="slotProps"
<current-user v-slot:default="slotProps">{
{slotProps.user.firstname}}
</current-user>
- 第二种,简写形式,
#default="slotProps"
<current-user #default="slotProps">{
{slotProps.user.firstname}}
</current-user>
- 第三种,如果只有默认slot,可省略
default
,即v-slot="slotProps"
<current-user v-slot="slotProps">{
{slotProps.user.firstname}}
</current-user>
- 第四种,使用解构赋值,
v-slot="{user}"
<current-user v-slot="{user}">{
{user.firstname}}
</current-user>
- 第五种,使用别名
v-slot="{user:person}"
<current-user v-slot="{user:person}">{
{person.firstname}}
</current-user>
- 第六种,设置默认值,
v-slot='{user={firstname:"Nicholas"}}'
<current-user v-slot='{user={firstname:"Nicholas"}}'>{
{user.firstname}}
</current-user>
作用域slot应用于组件复用
- 不使用作用域slot
<body><div id="root"><todo-list></todo-list></div>
</body>
import Vue from "vue";Vue.component("todo-list",{
template:'<ul>\<li v-for="todo in list"\v-bind:key="todo.id">\{
{todo.text}}\</li>\</ul>',data:function(){
return {
list:[{
id:"#1",text:"吃饭"},{
id:"#2",text:"睡觉"},{
id:"#3",text:"打豆豆"}]}}
})
const vm = new Vue({
el:"#root"
});
- 使用slot作用域
<body><div id="root"><todo-list v-slot:default="{todo}"><span v-if="todo.isDone">?</span>{
{todo.text}}</todo-list></div>
</body>
import Vue from "vue";Vue.component("todo-list",{
template:'<ul>\<li v-for="todo in list"\v-bind:key="todo.id">\<slot name="default" v-bind:todo="todo">\{
{todo.text}}\</slot>\</li>\</ul>',data:function(){
return {
list:[{
id:"#1",text:"吃饭",isDone:true},{
id:"#2",text:"睡觉",isDone:true},{
id:"#3",text:"打豆豆",isDone:false}]}}
})
const vm = new Vue({
el:"#root"
});