匿名插槽
如果插槽有默认值,而使用插槽的地方没有给插槽插入内容,那么默认显示插槽默认值。
<slot><button>默认值</button></slot>
具名插槽
要为具名插槽传入内容,我们需要使用一个含 v-slot 指令的 <template> 元素,并将目标插槽的名字传给该指令。
// my-component.vue
<template>
<slot name="header"></slot>
<slot>匿名插槽</slot>
<slot name="footer"></slot>
</template>
// 使用my-component.vue组件
<template>
<my-component>
<h1>我要传入匿名插槽</h1>
<template v-slot:header>
<h1>我要传入header</h1>
</template>
<template v-slot:footer>
<h1>我要传入footer</h1>
</template>
</my-component>
</template>
v-slot 有对应的简写 #,<template v-slot:header> 可以简写为 <template #header>
💣 不要在
slot上写样式进行布局,会被替换掉。可以嵌套一层div,在div上写样式。
动态插槽名
v-slot:[dynamicSlotName] 由使用者决定插槽名称。使用子组件时,给子组件传递一个 props 属性 name。获取 data 中的 name 属性值,作为 v-slot 指令的值。
使用my-component组件中的插槽
<my-component :name="dynamicSlotName">
<template v-slot:[dynamicSlotName]>
<p>我是动态插槽名插入的内容</p>
</template>
</my-component>
<script setup>
const dynamicSlotName = 'content'
</script>
带插槽的my-component,接收 props 属性作为插槽名
<template>
<slot :name="props.name"></slot>
</template>
<script setup>
import { defineProps } from 'vue'
const props = defineProps({
name: {
type: String
}
})
</script>
作用域插槽
插槽的内容无法访问到子组件的状态。然而在某些场景下插槽的内容可能想要同时使用父组件域内和子组件域内的数据。要做到这一点,我们需要一种方法来让子组件在渲染时将一部分数据提供给插槽。
匿名作用域插槽
如果插槽没有命名则 <slot> 会带有隐含的名字 default ,相应的父组件中要使用 v-slot:default="slotProps" 且可以省略为 v-slot='slotProps'。
// 子组件
<template>
<div class="item">
<slot :data="data"></slot>
</div>
</template>
<script setup>
import {ref} from 'vue'
const data = ref([
{name: '张三', age: 18},
{name: '李四', age: 19},
{name: '王五', age: 20}
])
</script>
// 父组件
<children>
<template v-slot="slotProps">
<ul class="item" v-for="item in slotProps.data" :key="item.name">
<li>{{item.name}}-{{item.age}}</li>
</ul>
</template>
</children>
具名作用域插槽
// 子组件
<template>
<div class="item">
<slot name='item' :lists="lists"></slot>
</div>
</template>
<script setup>
import {ref} from 'vue'
const lists = ref([
{name: 'lxx', todo: 'eat'},
{name: 'xxx', todo: 'run'},
{name: 'xyy', todo: 'sleep'}
])
</script>
// 父组件中使用 Lists
<children>
<template v-slot:item="slotProps">
<span v-for="item in slotProps.lists">{{item.name}}-{{item.todo}}</span>
</template>
</children>