简介
在Vue3中,子组件的模板可以定义多个插槽(包括默认插槽和具名插槽等等),
而父组件在引用子组件时,可以根据需要 有选择性的为这些插槽插入内容。
如果父组件没有为某个插槽提供内容,那么子组件的模板中该插槽的位置将显示为该插槽的默认内容(如果有的话),或者简单地留空。
下面将这几种插槽一一介绍一下:
1. 默认插槽(Default Slot)
定义:没有指定名称的插槽,用于接收父组件传递的未明确指定插槽名称的内容。
用法:在子组件中使用<slot></slot>
定义默认插槽的位置,父组件中直接放在子组件标签内的内容会被渲染到该位置。
父组件
<script lang="ts" setup>
import DemoChild from "@/views/control/DemoChild.vue";
</script>
<template>
<div>
<!--子组件-->
<DemoChild>
<!--默认插槽-->
<div>这是默认插槽的内容是,测试测试测试</div>
</DemoChild>
</div>
</template>
<style lang="scss" scoped>
</style>
子组件 DemoChild.vue
<script lang="ts" setup>
import {ref, computed} from 'vue'
</script>
<template>
<div>
这是子组件
<!--默认插槽-->
<slot></slot>
</div>
</template>
<style lang="scss" scoped>
</style>
效果
<script lang="ts" setup>
import {ref, computed} from 'vue'
</script>
<template>
<div>
这是子组件
<!--默认插槽-->
<div>这是默认插槽的内容是,测试测试测试</div>
</div>
</template>
<style lang="scss" scoped>
</style>
2. 具名插槽(Named Slots)
定义:带有名称的插槽,用于接收父组件中明确指定插槽名称的内容。
用法:在子组件中使用<slot name=“插槽名称”></slot>
定义具名插槽,父组件中通过<template v-slot:插槽名称>
或简写为<template #插槽名称>
来指定内容应该插入哪个具名插槽。
父组件
<script lang="ts" setup>
import DemoChild from "@/views/control/DemoChild.vue";
</script>
<template>
<div>
<!--子组件-->
<DemoChild>
<!--具名插槽-->
<template #header>
<div>这是 header 具名插槽的简写形式</div>
</template>
<template v-slot:header2>
<div>这是 header2 具名插槽的完整形式</div>
</template>
</DemoChild>
</div>
</template>
<style lang="scss" scoped>
</style>
子组件
<script lang="ts" setup>
import {ref, computed} from 'vue'
</script>
<template>
<div>
<!--具名插槽-->
<slot name="header"></slot>
<slot name="header2"></slot>
</div>
</template>
<style lang="scss" scoped>
</style>
效果
3.作用域插槽(Scoped Slots)
定义:一种特殊的插槽,允许子组件将数据暴露给父组件的插槽内容。
用法:在子组件中,通过<slot :数据名=“数据值”></slot>
将数据传递给插槽;在父组件中,通过<template v-slot:插槽名称=“slotProps”>
接收数据,并使用slotProps
来访问传递过来的数据。
父组件(只准有一个相同的具名插槽)
<script lang="ts" setup>
import {ref, computed} from 'vue'
import DemoChild from "@/views/control/DemoChild.vue";
</script>
<template>
<div>
<!--子组件-->
<DemoChild>
<!--作用域插槽 完整形式-->
<template v-slot:footer="obj">
<p>父组件来控制插槽内容11:{{ obj }}</p>
</template>
<!--作用域插槽 完整结构形式-->
<template v-slot:footer="{ obj }">
<p>父组件来控制插槽内容22解构:{{ obj }}</p>
</template>
<!--作用域插槽 简写形式-->
<template #footer="obj">
<p>父组件来控制插槽内容11:{{ obj }}</p>
</template>
<!--作用域插槽 简写结构形式-->
<template #footer="{ obj }">
<p>父组件来控制插槽内容11:{{ obj }}</p>
</template>
</DemoChild>
</div>
</template>
<style lang="scss" scoped>
</style>
子组件
<script lang="ts" setup>
import {ref, computed} from 'vue'
const obj = ref({
name: '作用域插槽',
age: 23
})
</script>
<template>
<div>
<!--作用域插槽-->
<slot name="footer" :obj="obj"></slot>
</div>
</template>
<style lang="scss" scoped>
</style>
4. 动态插槽名(Dynamic Slot Names)
定义:允许插槽的名称是动态的,根据组件的状态或其他条件来决定使用哪个插槽。
用法:在父组件中,通过:slot=“动态名称”
来绑定插槽的名称,其中动态名称可以是一个计算属性、方法返回值或数据属性。
父组件
<script lang="ts" setup>
import {ref, computed} from 'vue'
import DemoChild from "@/views/control/DemoChild.vue";
const mySlotName1 = computed(() => 'name1')
const mySlotName2 = computed(() => 'name2')
</script>
<template>
<div>
<!--子组件-->
<DemoChild>
<!-- 动态插槽名 -->
<template v-slot:[mySlotName1]>
<p>动态插槽名1</p>
</template>
<!-- 缩写动态插槽名 -->
<template #[mySlotName2]>
<p>动态插槽名2</p>
</template>
</DemoChild>
</div>
</template>
<style lang="scss" scoped>
</style>
子组件
<script lang="ts" setup>
import {ref, computed} from 'vue'
const obj = ref({
name: '作用域插槽',
age: 23
})
</script>
<template>
<div>
<!--动态插槽插槽-->
<slot name="name1"></slot>
<slot name="name2"></slot>
</div>
</template>
<style lang="scss" scoped>
</style>
5. 插槽后备内容(Slot Fallback Content)
定义:当父组件没有为插槽提供内容时,子组件可以定义一些后备内容作为默认显示。
用法:在子组件的<slot>
标签内部直接放置的内容,如果父组件没有为该插槽提供内容,则显示这些后备内容。
子组件
<template>
<div>
<slot>
<!-- 后备内容:如果没有提供插槽内容,则显示这个 -->
<p>如果没有提供内容,将显示这段后备文本。</p>
</slot>
</div>
</template>
父组件
<script lang="ts" setup>
import DemoChild from "@/views/control/DemoChild.vue";
</script>
<template>
<div>
<!-- 提供了插槽内容,所以后备内容不会显示 -->
<DemoChild>
<div>提供了插槽内容,所以后备内容不会显示</div>
</DemoChild>
<!-- 没有提供插槽内容,将显示后备内容 -->
<DemoChild></DemoChild>
</div>
</template>
<style lang="scss" scoped>
</style>
以上就是vue3中 插槽的使用方式,如果对你有帮助的话,感谢点赞收藏。