Vue.js - 插槽slot的使用详解(默认内容、具名插槽、动态插槽名、作用域)
作者:hangge | 2026-04-02 08:37
在 Vue.js 中,插槽(Slot)是一种非常灵活、强大的组件内容分发机制。它允许父组件向子组件传递模板结构,而不是普通的数据,从而大大增强了组件的可扩展性与复用性。本文将从基础插槽开始,通过样例逐步讲解具名插槽、作用域插槽、动态插槽,帮助大家掌握插槽的使用。
(2)然后我们可以使用 MySlotCompnent.vue 组件及其插槽,这里为 MySlotCpn.vue 组件的插槽插入了不同的内容。
(3)运行效果如下,可以看到 MySlotCompnent.vue 组件中间的内容都是由使用者决定的。
(2)当我们使用 MySlotCompnent.vue 组件时,如果没有插入对应的内容,那么会显示插槽中的默认内容。
(2)我们创建一个 MySlotCompnent.vue 组件,里面有三个插槽,并且分别为插槽添加 name 属性。
(3)在为 MySlotCompnent.vue 组件具名插槽提供内容时,需要将提供的内容编写到对应的 <template> 元素中。接着,在 <template> 元素上使用 v-slot 指令,并通过冒号语法将目标插槽的名字传递给该指令。
(4)运行结果如下:
(3)在使用 MySlotCompnent.vue 组件时,首先为该组件传递了 data 中定义 name 变量(作为插槽的名称),接着在为 MySlotCompnent.vue 组件左边插槽提供内容时,传给 v-slot 指令的目标插槽名称也是动态绑定的 name 变量。
(4)保存代码后,页面依然可以正常显示。
(3)接着我们使用该组件。首先向 ShowNames.vue 组件传递 names 属性,接着在 ShowNames.vue 组件中的 <template> 元素上使用 v-slot:default 指令,即使用默认插槽。然后在 v-slot:default 指令等号(=)后,直接接收一个 slot props 对象(如 slotProps,该名称支持自定义)。最后,通过 slotProps 获取 ShowNames.vue 组件为插槽绑定的 item 和 index 数据。
(4)最终运行效果如下:
1,插槽的基本使用
(1)首先我们创建一个 MySlotCompnent.vue 组件,负责定义插槽,代码如下。可以看到,我们在该组件中添加了一个 <slot>,可在该 <slot> 中放入需要显示的内容,即让使用者决定显示的内容。
提示:<slot></slot> 是 <slot name="default></slot> 的简写。
<template>
<div class="my-component">
<div>我是头部</div>
<!--中间显示的内容用slot占位,因为内容是不确定的-->
<slot></slot>
<div>我是尾部</div>
</div>
</template>
<script>
export default {
name: 'MyComponent',
}
</script>
<style scoped>
.my-component {
border: solid 1px gray;
padding: 5px;
}
</style>
(2)然后我们可以使用 MySlotCompnent.vue 组件及其插槽,这里为 MySlotCpn.vue 组件的插槽插入了不同的内容。
<template>
<div class="my-component">
<!-- 1.默认没有插入内容 -->
<my-slot-compnent></my-slot-compnent>
<!-- 2.插入一个文本 -->
<my-slot-compnent>
欢迎访问hangge.com
</my-slot-compnent>
<!-- 3.插入一个元素 -->
<my-slot-compnent>
<button>我是按钮</button>
</my-slot-compnent>
<!-- 4.插入多个内容 -->
<my-slot-compnent>
<div>我是div</div>
<button>按钮1</button>
<button>按钮2</button>
</my-slot-compnent>
</div>
</template>
<script>
import MySlotCompnent from './MySlotCompnent.vue';
export default {
name: 'MyComponent',
components: {
MySlotCompnent
}
}
</script>
(3)运行效果如下,可以看到 MySlotCompnent.vue 组件中间的内容都是由使用者决定的。

2,插槽的默认内容
(1)在使用插槽的情况下,当没有提供插入的内容时,如果希望显示默认内容,那么这个默认内容只在没有提供插入内容的情况下才会显示。修改 MySlotCompnent.vue 组件,在插槽中添加默认内容,代码如下所示:
<template>
<div class="my-component">
<div>我是头部</div>
<!--中间显示的内容用slot占位,因为内容是不确定的-->
<slot>
这个是插槽的默认内容,只在没有提供插入的内容时,才会显示
</slot>
<div>我是尾部</div>
</div>
</template>
<script>
export default {
name: 'MyComponent',
}
</script>
<style scoped>
.my-component {
border: solid 1px gray;
padding: 5px;
margin: 10px;
}
</style>
(2)当我们使用 MySlotCompnent.vue 组件时,如果没有插入对应的内容,那么会显示插槽中的默认内容。

3,具名插槽的使用
(1)一个组件中可以存在多个插槽,如果我们希望这些插槽分别显示不同的内容,那么可以使用具名插槽,即为插槽起一个名字。
提示:<slot> 元素有一个特殊的 name 属性, 而不带有 name 属性的插槽也会带有隐含的 name="default"。
(2)我们创建一个 MySlotCompnent.vue 组件,里面有三个插槽,并且分别为插槽添加 name 属性。
<template>
<div class="nav-bar">
<div class="left">
<slot name="left"></slot><!--1.为插槽起一个left名字-->
</div>
<div class="center">
<slot name="center"></slot><!--2.为插槽起一个center名字-->
</div>
<div class="right">
<slot name="right"></slot><!--3.为插槽起一个right名字-->
</div>
</div>
</template>
<script>
export default {
name: 'MyComponent',
}
</script>
<style scoped>
.nav-bar {
border: solid 1px gray;
padding: 5px;
display: flex;
}
.center {
flex: 1;
text-align: center;
align-items: center;
}
</style>
(3)在为 MySlotCompnent.vue 组件具名插槽提供内容时,需要将提供的内容编写到对应的 <template> 元素中。接着,在 <template> 元素上使用 v-slot 指令,并通过冒号语法将目标插槽的名字传递给该指令。
<template>
<div class="my-component">
<my-slot-compnent>
<template v-slot:left>
<button class="btn">左边的按钮</button>
</template>
<template v-slot:center>
<h1>中间的标题</h1>
</template>
<template v-slot:right>
<button class="btn">右边的按钮</button>
</template>
</my-slot-compnent>
</div>
</template>
<script>
import MySlotCompnent from './MySlotCompnent.vue';
export default {
name: 'MyComponent',
components: {
MySlotCompnent
}
}
</script>
<style scoped>
.my-component {
padding: 10px;
}
</style>
- v-slot:的简写为 #,因此 <template v-slot:header> 可简写为 <template #header>,下面代码功能与上面相同。
<template>
<div class="my-component">
<my-slot-compnent>
<template #left>
<button class="btn">左边的按钮</button>
</template>
<template #center>
<h1>中间的标题</h1>
</template>
<template #right>
<button class="btn">右边的按钮</button>
</template>
</my-slot-compnent>
</div>
</template>
<script>
import MySlotCompnent from './MySlotCompnent.vue';
export default {
name: 'MyComponent',
components: {
MySlotCompnent
}
}
</script>
<style scoped>
.my-component {
padding: 10px;
}
</style>
(4)运行结果如下:

4,动态插槽名的使用
(1)上述我们使用的插槽名称都是固定的,例如 v-slot:left、v-slot:center 等。其实,我们还可以通过 v-slot:[dynamicSlotName] 方式动态绑定一个插槽的名称。
(2)下面修改 MySlotCompnent 组件,使左边布局插槽的名称来自 props 中的 name 属性。
<template>
<div class="nav-bar">
<div class="left">
<slot :name="name"></slot><!--动态添加插槽的名称,由外部使用者决定-->
</div>
<div class="center">
<slot name="center"></slot><!--2.为插槽起一个center名字-->
</div>
<div class="right">
<slot name="right"></slot><!--3.为插槽起一个right名字-->
</div>
</div>
</template>
<script>
export default {
name: 'MyComponent',
props: {
name: String // 接收插槽的名称
}
}
</script>
<style scoped>
.nav-bar {
border: solid 1px gray;
padding: 5px;
display: flex;
}
.center {
flex: 1;
text-align: center;
align-items: center;
}
</style>
(3)在使用 MySlotCompnent.vue 组件时,首先为该组件传递了 data 中定义 name 变量(作为插槽的名称),接着在为 MySlotCompnent.vue 组件左边插槽提供内容时,传给 v-slot 指令的目标插槽名称也是动态绑定的 name 变量。
<template>
<div class="my-component">
<my-slot-compnent :name="name"> <!-- 传递插槽名称给MySlotCompnent.vue组件-->
<template v-slot:[name]>
<button class="btn">左边的按钮</button>
</template>
<template #center>
<h1>中间的标题</h1>
</template>
<template #right>
<button class="btn">右边的按钮</button>
</template>
</my-slot-compnent>
</div>
</template>
<script>
import MySlotCompnent from './MySlotCompnent.vue';
export default {
name: 'MyComponent',
components: {
MySlotCompnent
},
data() {
return {
name: 'hangge' // 传递插槽名称
}
},
}
</script>
- v-slot:的简写为 #,因此 <template v-slot:[name]> 可简写为 <template #[name]>,下面代码功能与上面相同。
<template>
<div class="my-component">
<my-slot-compnent :name="name"> <!-- 传递插槽名称给MySlotCompnent.vue组件-->
<template #[name]>
<button class="btn">左边的按钮</button>
</template>
<template #center>
<h1>中间的标题</h1>
</template>
<template #right>
<button class="btn">右边的按钮</button>
</template>
</my-slot-compnent>
</div>
</template>
<script>
import MySlotCompnent from './MySlotCompnent.vue';
export default {
name: 'MyComponent',
components: {
MySlotCompnent
},
data() {
return {
name: 'hangge' // 传递插槽名称
}
},
}
</script>
<style scoped>
.my-component {
padding: 10px;
}
</style>
(4)保存代码后,页面依然可以正常显示。
5,作用域插槽
(1)由于组件存在渲染作用域,每个组件只能访问自己作用域中的内容,但有时我们希望插槽可以访问子组件中的内容。这种情况在实际开发中使用得非常多,也非常重要。这时,可以使用 Vue.js 提供的作用域插槽。
- 例如,当一个组件被用于渲染一个数组元素时,我们在使用插槽的同时,希望能够在插槽中自定义每项内容。
(2)我们这里创建一个名为 ShowNames.vue 的组件,代码如下。首先该组件接收 names 属性,接着在 template 中使用 v-for 指令遍历 names 数组,数组中每项显示的内容使用插槽占位,让使用者决定显示的内容。然后将遍历数组的 item 和 index 绑定到插槽的属性上,目的是让使用该插槽的人可以通过带值的 v-slot 指令获取插槽提供的属性,如 item 和 index。
提示:我们可以为插槽添加任意数量的属性。另外,在插槽中定义的属性称为插槽的属性(slot prop)
<template>
<div class="show-names">
<template v-for="(item, index) in names">
<!-- 为插槽添加item和index属性,并绑定item和index数据。item和index称为slot prop -->
<slot :item="item" :index="index"></slot>
</template>
</div>
</template>
<script>
export default {
props: {
names: {
type: Array,
default: () => []
}
}
}
</script>
(3)接着我们使用该组件。首先向 ShowNames.vue 组件传递 names 属性,接着在 ShowNames.vue 组件中的 <template> 元素上使用 v-slot:default 指令,即使用默认插槽。然后在 v-slot:default 指令等号(=)后,直接接收一个 slot props 对象(如 slotProps,该名称支持自定义)。最后,通过 slotProps 获取 ShowNames.vue 组件为插槽绑定的 item 和 index 数据。
<template>
<div class="app">
<show-names :names="names">
<!-- v-slot:default后面的值slotProps是插槽属性的集合。其中,slotProps可任意命名 -->
<template v-slot:default="slotProps">
<span class="name">{{ slotProps.item }} - {{ slotProps.index }}</span>
</template>
</show-names>
</div>
</template>
<script>
import ShowNames from './ShowNames.vue';
export default {
name: 'BlankView',
components: {
ShowNames
},
data() {
return {
names: ["hangge", "baidu", "google"]
}
}
}
</script>
<style scoped>
.name {
border: solid 1px gray;
padding: 5px;
margin: 5px;
}
</style>
(4)最终运行效果如下:

全部评论(0)