插槽的概念
你可以把插槽想象成是预留给父组件填充内容的占位符。这样一来,父组件就可以根据需要插入 HTML 结构或者其他组件了。
插槽分为:匿名插槽、具名插槽、作用域插槽
匿名插槽
当子组件中有多个插槽时,父组件传入的内容会填充到子组件中的第一个插槽中。
子组件:
<template>
<div>
我是子组件
<slot></slot>
</div>
</template>
父组件:
<script setup lang="ts">
import HomeView from "./views/HomeView.vue";
</script>
<template>
<HomeView>
<div>我是插槽的内容</div>
</HomeView>
</template>
具名插槽
在子组件中定义一个带有 name 属性的 slot 标签,父组件可以通过 slot 属性将内容插入到指定的插槽中。
子组件:
<template>
<div>
我是子组件
<slot name="content"></slot>
</div>
</template>
父组件:
<script setup lang="ts">
import HomeView from "./views/HomeView.vue";
</script>
<template>
<HomeView>
<template v-slot:content>
<div>我是插槽content的内容</div>
</template>
</HomeView>
</template>
上面的 v-slot:content 可以简写为:#content
<script setup lang="ts">
import HomeView from "./views/HomeView.vue";
</script>
<template>
<HomeView>
<template #content>
<div>我是插槽content的内容</div>
</template>
</HomeView>
</template>
作用域插槽
子组件可以在插槽中传递数据给父组件,父组件可以通过 v-slot 指令接收这些数据,并根据需要进行处理。
子组件:
<script setup lang="ts">
import { ref } from "vue";
const m=ref({a:1})
</script>
<template>
<div>
我是子组件
<!-- 匿名作用域插槽 -->
<slot :data1="m"></slot>
<!-- 具名作用域插槽 -->
<slot name="content" :data2="m"></slot>
</div>
</template>
父组件:
<script setup lang="ts">
import HomeView from "./views/HomeView.vue";
</script>
<template>
<HomeView>
<template v-slot="{data1}">
<div>{{data1}}</div>
</template>
<template v-slot:content="{data2}">
<div>{{ data2 }}</div>
</template>
</HomeView>
</template>
上面的具名作用域插槽 v-slot:content="{data2} 也可以简写为:#content="{data2}
动态插槽
对于具名插槽和具名作用域插槽,我们可以定义一个变量,给这个变量赋不同的插槽的名字,这样就可以动态显示对应名字的插槽。
子组件:
<template>
<div>
我是子组件
<slot name="top"></slot>
<slot name="middle"></slot>
</div>
</template>
父组件:
<script setup lang="ts">
import { ref } from "vue";
import HomeView from "./views/HomeView.vue";
const slotName=ref('top')
// 改变slotName的值,将其值设置为slot的对应名字,可以动态切换插槽显示
const changeSlotName=()=>{
slotName.value="middle"
}
</script>
<template>
<HomeView>
<template #[slotName]>
<div>我是{{slotName}}插槽的内容</div>
<button @click="changeSlotName">按钮</button>
</template>
</HomeView>
</template>