# 1.slot 中默认内容
// App.vue | |
<template> | |
<div> | |
<!-- 大写的组件名可写成小写用 - 相连 --> | |
<my-slot-cpn></my-slot-cpn> | |
<my-slot-cpn></my-slot-cpn> | |
<my-slot-cpn></my-slot-cpn> | |
</div> | |
</template> | |
<script> | |
import MySlotCpn from './MySlotCpn.vue'; | |
export default { | |
components: { | |
MySlotCpn | |
} | |
} | |
</script> | |
<style scoped></style> |
// MySlotCpn.vue | |
<template> | |
<div> | |
<h3>组件开始</h3> | |
<slot> | |
<span>我是默认的span元素</span> | |
</slot> | |
<slot> | |
<p>我是默认的p元素</p> | |
</slot> | |
<h3>组件结束</h3> | |
</div> | |
</template> | |
<script> | |
export default { } | |
</script> | |
<style scoped></style> |
参考结果:

# 2. 替换 slot 中的元素
// App.vue | |
<template> | |
<div> | |
<!-- 大写的组件名可写成小写用 - 相连 --> | |
<my-slot-cpn> | |
<h3>我插入了一个h3标签</h3> | |
</my-slot-cpn> | |
<my-slot-cpn></my-slot-cpn> | |
</div> | |
</template> | |
<script> | |
import MySlotCpn from './MySlotCpn.vue'; | |
export default { | |
components: { | |
MySlotCpn | |
} | |
} | |
</script> | |
<style scoped></style> |
参考结果:
# 3. 具名插槽 name
// App.vue | |
<template> | |
<div> | |
<nav-bar :name="name"> | |
<!-- 完整写法:v-slot: --> | |
<template v-slot:left></template> | |
<!-- 简写:(v-slot:) 替换为字符 # --> | |
<template #center> | |
<a>左边的a标签</a> | |
</template> | |
<template #right> | |
<span>中间的span</span> | |
</template> | |
<!-- 直接使用 name,代表是叫 name 的插槽,必须用 v-slot:[name] --> | |
<template #[name]> | |
<button>右边的按钮</button> | |
</template> | |
</nav-bar> | |
</div> | |
</template> | |
<script> | |
import NavBar from './NavBar.vue'; | |
export default { | |
components: { | |
NavBar | |
}, | |
data() { | |
return { | |
name: "Neko" | |
} | |
} | |
} | |
</script> | |
<style scoped></style> |
// NavBar.vue | |
<template> | |
<div class="nav-bar"> | |
<!-- 使用 name 给 slot 起个名字 --> | |
<!-- 不写 name 默认 === <slot name="default"></slot> 这种写法 --> | |
<div class="left"> | |
<slot name="left"></slot> | |
</div> | |
<div class="center"> | |
<slot name="center"></slot> | |
</div> | |
<div class="right"> | |
<slot name="right"></slot> | |
</div> | |
<!-- 动态插槽名 name --> | |
<div class="addition"> | |
<slot :name="name"></slot> | |
</div> | |
</div> | |
</template> | |
<script> | |
export default { | |
// 使用 props 接收 | |
props: { | |
name: String | |
} | |
} | |
</script> | |
<style scoped> | |
.nav-bar { | |
display: flex; | |
} | |
.left, .right, .center { | |
height: 44px; | |
} | |
.left, .right, .addition { | |
width: 80px; | |
background-color: red; | |
} | |
.center { | |
flex: 1; | |
background-color: pink; | |
} | |
</style> |
参考结果:

# 4. 作用域插槽
// App.vue | |
<template> | |
<div> | |
<show-names :names="names"> | |
<!-- 没有名字默认是 default --> | |
<template v-slot:default> | |
</template> | |
</show-names> | |
<show-names :names="names"> | |
<!-- 赋一个值 slotProps,从这个 slotProps 里面取出属性。slotProps 可随意起名 --> | |
<template v-slot="slotProps"> | |
<strong>{{ slotProps.item }}-{{ slotProps.index }}</strong> | |
</template> | |
</show-names> | |
<!-- 独占默认插槽缩写 可以不使用 template --> | |
<show-names :names="names" v-slot="Neko"> | |
<button>{{ Neko.item }}-{{ Neko.index }}</button> | |
</show-names> | |
<!-- 注意:如果还有其他的具名插槽,那么默认插槽也必须使用 template 来编写 --> | |
<show-names :names="names"> | |
<template v-slot:default="Neko"> | |
<button>{{ Neko.item }}-{{ Neko.index }}</button> | |
</template> | |
<template v-slot:Neko> | |
<h2>我是Neko</h2> | |
</template> | |
</show-names> | |
</div> | |
</template> | |
<script> | |
import ShowNames from './ShowNames.vue'; | |
export default { | |
components: { | |
ShowNames | |
}, | |
data() { | |
return { | |
names: ["Neko", "Nico", "Aimer", "Aphrodite"] | |
} | |
} | |
} | |
</script> | |
<style scoped></style> |
// ShowNames.vue | |
<template> | |
<div> | |
<template v-for="(item, index) in names" :key="item"> | |
<!-- 定义属性:item :index --> | |
<slot :item="item" :index="index"></slot> | |
<slot name="Neko">--default--</slot> | |
</template> | |
</div> | |
</template> | |
<script> | |
export default { | |
props: { | |
names: { | |
type: Array, | |
default: () => [] | |
} | |
} | |
} | |
</script> | |
<style scoped></style> |
参考结果:
