1)插槽由来和分类
在某些场景中,我们可能想要在父组件为子组件传递一些模板片段,让子组件在它们的组件中渲染这些片段。
这就是插槽的作用。插槽分多种,默认插槽、具名插槽、条件插槽、动态插槽、作用域插槽。
2)插槽类型和举栗子
1.默认插槽
<slot></slot>
举栗子:
父组件:子组件的插槽写在哪里,父组件传递的内容就在哪里展示
<template>
<div>我是父组件</div>
<son>
我是父组件给子组件的插槽
</son>
</template>
<script setup>
import son from './son.vue'
</script>
子组件:
<template>
<h3>我是子组件</h3>
<br>
<slot></slot>
</template>
2.具名插槽,一个子组件可以存在多个
<slot name="header"></slot>
<slot name="footer"></slot>
父组件:父组件使用具名插槽有2种写法
<template>
<div>我是父组件</div>
<son>
我是父组件给子组件的插槽
<!-- 具名插槽写法1 -->
<!-- <template v-slot:header>
header插槽
</template> -->
<!-- 具名插槽写法2 -->
<template #header>
header插槽
</template>
</son>
</template>
子组件:
<template>
<h3>我是子组件</h3>
<br>
<slot></slot>
<br>
<slot name="header"></slot>
</template>
3.条件插槽,主要是为了给插槽提供额外的样式
<div v-if="slots.header" class="trans-header">
<slot name="header"></slot>
</div>
<div v-if="slots.footer" class="trans-footer">
<slot name="footer"></slot>
</div>
举栗子:
父组件:
<template>
<div>我是父组件</div>
<son>
<template #header>
header插槽
</template>
<template #footer>
footer插槽
</template>
</son>
</template>
<script setup>
import son from './son.vue'
</script>
子组件:
<template>
<h3>我是子组件</h3>
<br>
<slot></slot>
<br>
<div v-if="slots.header" class="trans-header">
<slot name="header"></slot>
</div>
<div v-if="slots.footer" class="trans-footer">
<slot name="footer"></slot>
</div>
</template>
<script setup>
import { onMounted, useSlots } from "vue";
const slots = useSlots()
onMounted(() => {
// 可以通过slots判断传递了哪些插槽
console.log(slots);
})
</script>
4.动态插槽,动态传入插槽名
<son>
<!-- 该属性dynamicSlotName为动态数据,在js定义并传递 -->
<template v-slot:[dynamicSlotName]>
...
</template>
<!-- 缩写为 -->
<template #[dynamicSlotName]>
...
</template>
</son>
5.作用域插槽
父组件:父组件传递给子组件的数据,可以通过插槽再次传递给父组件使用,封装组件时非常常用
<template>
<div>我是父组件</div>
<son :obj1="obj1" :obj2="obj2">
我是父组件给子组件的插槽
<template #header="slot">
header插槽{{ slot.obj1 }}
</template>
<template #footer="slot">
footer插槽{{ slot.obj2 }}
</template>
</son>
</template>
<script setup>
import { reactive } from 'vue';
import son from './son.vue'
const obj1 = reactive({ name: '羊羊', age: 12 });
const obj2 = reactive({ name: '猫猫', age: 2 });
</script>
子组件:
<template>
<h3>我是子组件</h3>
<br>
<slot></slot>
<br>
<slot name="header" :obj1="obj1"></slot>
<slot name="footer" :obj2="obj2"></slot>
</template>
<script setup>
const props = defineProps({
obj1: {
type: Object, default: () => { }
},
obj2: {
type: Object, default: () => { }
},
})
</script>
如有不足,欢迎指正。
不要忽视你达成的每个小练习,它是你前进路上的垫脚石。冲!