1. 插槽指令
- 父组件给子组件传递一些模板片段,让子组件在它们的组件中渲染这些片段。
- 使用
v-slot:插槽名称
绑定插槽,简写:#插槽名称
- 动态插槽名:
v-slot
绑定一个变量,可以动态改变插槽名
2. 具名插槽
- 需要在父组件中使用
v-slot
指令绑定插槽名称 - 并且在子组件的
<slot>
标签中绑定 name 属性 - 父组件中使用
v-slot
指令绑定的插槽名和子组件中 <slot>
标签绑定的 name
属性中值要一样 - 如果子组件存在多个插槽,需要使用具名插槽,以避免插槽内容无法正确的渲染到指定位置
<template>
<Children>
<template v-slot:header>
<div>我是header</div>
</template>
</Children>
</template>
<script lang="ts" setup>
import Children from "./children.vue";
</script>
<template>
<div>
<slot name="header"></slot>
</div>
</template>
3. 默认插槽
- 当父组件中没有使用
v-slot
指令绑定插槽名称,直接向子组件传递插槽内容 - 并且子组件的
<slot>
标签中没有绑定 name
属性 - 如果子组件中只有一个插槽,可以使用默认插槽
- 如果子组件的插槽全都没有绑定
name
属性,那么每个插槽都会接收到父组件传递的插槽内容,导致子组件内所有的插槽都是重复的相同的插槽
<template>
<Children>插槽内容</Children>
</template>
<script lang="ts" setup>
import Children from "./children.vue";
</script>
<template>
<div>
<slot></slot>
</div>
</template>
<template>
<div>
<slot>
<p>插槽默认内容</p>
</slot>
</div>
</template>
4. 插槽默认值
- 如果父组件传递了插槽内容,则渲染父组件传递的内容
- 如果父组件未传递插槽内容,则渲染插槽的默认内容
<template>
<Children>
<p>父组件传递的插槽内容</p>
</Children>
<Children></Children>
</template>
<script lang="ts" setup>
import Children from "./children.vue";
</script>
<template>
<div>
<slot>
<p>插槽默认内容</p>
</slot>
</div>
</template>
5. 渲染作用域
- 子组件的渲染作用域:
除 <slot>内容</slot>
标签中间的内容区域外,整个 vue 文件都是子组件的直属区域 - 父组件的渲染区域:
整个父组件 vue 文件,以及子组件中 <slot>内容</slot>
标签中间的内容区域
6. 作用域插槽
- 带有
props
的 <slot>
叫做作用域插槽 - 父组件通过
v-slot
指令绑定一个变量 slotProps
,用于接收子组件传递的数据 - 子组件通过
v-bind
提供的数据,这些数据会被 <slot>
标签传递给父组件, - 变量
slotProps
是个对象,子组件提供的数据会存储在其中 - 插槽上的 name 是一个 Vue 特别保留的 attribute,不会作为 props 传递给插槽
<template>
<div>srud示例</div>
<Children v-slot:header="slotProps">
<p>{{ slotProps.count }} + {{ slotProps.count }}</p>
</Children>
</template>
<script setup>
import Children from "./children.vue";
</script>
<template>
<div>
<slot :count="count" :msg="msg" name="header"></slot>
</div>
</template>
<script lang="ts" setup>
const count = "子组件数据";
const msg = "数据2";
</script>