Vue3自定义组件中如何判断使用了那些具名插槽??
🌏业务场景介绍:
有时候我们自定义的组件中有会多个插槽,每个插槽有一个值唯一的name 属性,这种插槽称之为具名插槽 。
当在父组件中使用具名插槽 时,与具名插槽 的name 属性相对应的template 中的内容将会替换该插槽的位置。
那么,在自定义组件 中,我们如何才能知道,在父组件 中到底使用了该组件的哪些插槽了呢??
请看下文详细介绍!!👇
<!-- ProSlot.vue -->
<script lang="ts" setup>
</script>
<template>
<div class="slot">
<slot>这是默认插槽</slot>
<br/>
<slot name="pro">这是pro插槽</slot>
</div>
</template>
<style lang="scss" scoped>
.slot {
margin: 0 auto;
width: 200px;
height: 100px;
border: 5px solid skyblue;
background-color: pink;
}
</style>
<ProSlot> </ProSlot>
<ProSlot>
这些内容由默认由默认插槽渲染
</ProSlot>
<ProSlot>
这些内容由默认由默认插槽渲染
<template #pro>
这些内容将由pro插槽渲染
</template>
</ProSlot>
- 4??在vue3中我们可以通过调用
getCurrentInstance() 方法来获取内部组件实例,但是它并不能当做this 的代替方案,因为getCurrentInstance 只能在 setup 或生命周期钩子中调用。 - 在组件内部获取的实例上挂载了
slots 属性,该属性收集了当前组件已经被使用的插槽name,根据该特点可以我们灵活地应对需求。 - 使用
getCurrentInstance 获取组件内部实例:
<!-- ProSlot.vue -->
<script lang="ts" setup>
import { onMounted, ComponentInternalInstance, getCurrentInstance } from 'vue'
const { slots } = getCurrentInstance() as ComponentInternalInstance
onMounted(() => {
console.log(slots);
})
</script>
<template>
<div class="slot">
<slot>这是默认插槽</slot>
<br/>
<slot name="pro">这是pro插槽</slot>
</div>
</template>
<style lang="scss" scoped>
.slot {
margin: 0 auto;
width: 400px;
height: 100px;
border: 5px solid skyblue;
background-color: pink;
}
</style>
<ProSlot>
<template #pro>
这些内容将由pro插槽渲染
</template>
</ProSlot>
此时,slots 只存在pro 属性。
<ProSlot>
这些内容由默认由默认插槽渲染
</ProSlot>
此时,slots 只存在default 属性。
🚀🌲🌏🛸?? 根据以上实验,可以了解到,通过获取组件内部实例上挂载的slots 即可判断该组件的哪些插槽被使用了。
下面是完整示例:
<!-- ProSlot.vue -->
<script lang="ts" setup>
import { onMounted, ComponentInternalInstance, getCurrentInstance } from 'vue'
const { slots } = getCurrentInstance() as ComponentInternalInstance
onMounted(() => {
console.log(slots);
if(slots?.default) {
console.log('使用了默认插槽');
}
if(slots?.pro) {
console.log('使用了pro插槽');
}
})
</script>
<template>
<div class="slot">
<slot>这是默认插槽</slot>
<br/>
<slot name="pro">这是pro插槽</slot>
</div>
</template>
<style lang="scss" scoped>
.slot {
margin: 0 auto;
width: 400px;
height: 100px;
border: 5px solid skyblue;
background-color: pink;
}
</style>
<script lang="ts" setup>
import ProSlot from '@/components/ProSlot.vue'
</script>
<template>
<ProSlot>
这些内容由默认由默认插槽渲染
<template #pro>
这些内容将由pro插槽渲染
</template>
</ProSlot>
</template>
<style lang="scss" scoped>
</style>
- 输出结果如下图:
📜参考:https://v3.cn.vuejs.org/api/composition-api.html#getcurrentinstance
|