<button class="fancy-btn">
<slot></slot> <!-- 插槽出口 -->
</button>
<slot>
元素是一个插槽出口 (slot outlet),标示了父元素提供的插槽内容 (slot content) 将在哪里被渲染。
// 定义一个Child.vue 子组件
<template>
<section class="child">
<h2>我是Child组件</h2>
// 匿名插槽(默认插槽)
<slot></slot>
// 如果子组件中没有使用插槽,父组件如果需要往子组件中填充模板内容或者html片段, 是没无法实现的
// 具名插槽(有名字的 named slots)
<h2>header插槽</h2>
<header>
<slot name="header"></slot>
</header>
// 传递参数给插槽
<main>
<slot name="main" :dataSlot="data"></slot>
</main>
<h2>footer插槽</h2>
<footer>
<slot name="footer"></slot>
</footer>
<!-- 传递props的插槽 -->
<div>
<slot name="propSlot" :text="greetingText" :count="1"></slot>
</div>
// 动态插槽
<template v-slot:[dynamicSlotName]>
...
</template>
<!-- 缩写为 -->
<template #[dynamicSlotName]>
...
</template>
</section>
</template>
<script setup>
import { ref } from 'vue'
const greetingText = ref('hello')
const data = ref(['Apple', 'Peach', 'Mango', 'Banana', 'Cherry'])
</script>
// 定义一个Parent.vue
<template>
<section class="parent">
<h2>我是Parent组件</h2>
<Child>
// 默认插槽
<section>{{ msg }}</section>
// 父组件填充内容时通过 v-slot:[name] 的方式指定到对应的插槽中
// slot 存在于子组件,它有个name属性,用于指定插槽的名字
// v-slot 指令用在父组件(或者使用参数形式 v-slot:footer, 也可以简写为 #footer),最终页面展示结果是父组件
// v-slot 只能用在组件或者 template 标签上
// 具名插槽 <slot name="name"></slot>
<template v-slot:header>
<h3>{{ headerText }}</h3>
</template>
// 作用域插槽
<template #main="{ dataSlot }">
<ul v-for="item in dataSlot" :key="item">
<li>{{ item }}</li>
</ul>
</template>
<template #footer>
<h3>{{ footerText }}</h3>
</template>
// 接收slot传递的props
<template #propSlot="{ text, count }">
<div>{{ text }} {{ count }}</div>
</template>
</Child>
</section>
</template>
<script setup>
import { ref } from 'vue'
import Child from './Child.vue';
const msg = ref("我是子组件插槽的一个 默认 内容")
const headerText = ref('我是子组件的 header 内容')
const footerText = ref('我是子组件的 footer 内容')
</script>