插槽:插槽语法是Vue 实现的内容分发 API,用于复合组件开发。该技术在通用组件库开发中有大量应用。

一、匿名插槽

1
2
3
4
5
6
7
// comp1
<div>
<slot></slot>
</div>

// parent
<comp>hello</comp>

二、具名插槽

内容分发到子组件指定位置

1
2
3
4
5
6
7
8
9
10
11
12
// comp2
<div>
<slot></slot>
<slot name="content"></slot>
</div>

// parent
<comp>
// 默认插槽用default做参数 具名插槽用插槽名做参数
<template v-slot:default>具名插槽</tempalte>
<template v-slot:content>内容...</template>
</comp>

三、作用域插槽

分发内容要用到子组件中的数据

1
2
3
4
5
6
7
8
9
10
11
<div>
<slot :foo="foo"></slot>
</div>

// parent
<comp>
// 把v-slot的值指定为作用域上下文对象
<tempalte v-slot:default="slotProps">
来自子组件数据:{{slotProps.foo}}
</tempalte>
</comp>

四、实例代码

子组件代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
// 子组件 Layout.vue
<template>
<div>
<div class="header">
<slot name="header"></slot>
</div>
<div class="body">
<slot></slot>
</div>
<div class="footer">
<slot name="footer" :fc="footerContent"></slot>
</div>
</div>
</template>

<script>
export default {
data() {
return {
remark: [
'好好学习,天天向上',
'学习永远不晚',
'学习知识要善于思考,思考,再思考',
'学习的敌人是自己的满足,要认真学习一点东西,必须从不自满开始',
'构成我们学习最大障碍的是已知的东西,而不是未知的东西',
'在今天和明天之间,有一段很长的时间;趁你还有精神的时候,学习迅速办事',
'三人行必有我师焉;择其善者而从之,其不善者而改之'
]
}
},
computed: {
footerContent() {
return this.remark[new Date().getDay() - 1]
}
},
}
</script>

<style scoped>
.header {
background-color: rgb(252, 175, 175);
}
.body {
display: flex;
background-color: rgb(144, 250, 134);
min-height: 100px;
align-items: center;
justify-content: center;
}
.footer {
background-color: rgb(114, 116, 255);
}
</style>

父组件代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
//父组件 index.vue
<template>
<div>
<h2>插槽</h2>
<!-- 插槽 -->
<Layout>
<!-- 具名插槽 -->
<template v-slot:header>全栈工程师</template>
<!-- 匿名插槽 -->
<template>content...</template>
<!-- 作用域插槽 -->
<template v-slot:footer="{fc}">{{fc}}</template>
</Layout>
</div>
</template>

<script>
import Layout from '@/components/slots/Layout.vue'

export default {
components: {
Layout
},
}
</script>

<style scoped>

</style>