有時候我們會根據 slot 內容決定是否渲染,這時可以搭配 v-if
使用
eg. 如果父元件有傳值進來 slot 就顯示
<template>
<div class="card">
<div v-if="$slots.header" class="header">
<slot name="header"></slot>
</div>
<div v-if="$slots.default" class="content">
<slot></slot>
</div>
<div v-if="$slots.footer" class="footer">
<slot name="footer"></slot>
</div>
</div>
</template>
<style scoped>
.card {
border:1px solid #ddd;
border-radius:8px;
padding:12px;
}
.header {
font-weight:700;
margin-bottom:8px;
}
.footer {
margin-top:8px;
color:#666;
}
</style>
<script setup>
import Card from './components/slot.vue'
const attr = 'box'
</script>
<template>
<div :class="attr">
<Card>
<template #header>details</template>
<p>content</p>
<p>content</p>
<p>content</p>
</Card>
<Card>
<template #header>notification</template>
<p>3 new messages</p>
<template #footer>now</template>
</Card>
<Card>
<p>pure content without<br> header & footer</p>
</Card>
</div>
</template>
<style scoped>
.box{
display: flex;
gap:3px;
text-align: center;
justify-content: center;
flex-direction: column;
font-size: x-large;
margin-left: 450px;
margin-top: 5px;
padding: 35px;
}
</style>
只傳入 header
,全部傳入 以及 僅有內容
slot
的名字也可以動態決定
eg.
<script setup>
import { ref } from 'vue'
import Card from './components/slot.vue'
const attr = ref('box')
const slotsNames = {
header: 'customize header',
footer: 'customize footer'
}
</script>
<template>
<div :class="attr">
<Card>
<template v-for="(content, name) in slotsNames":key="name" #[name]>
{{ content }}
</template>
</Card>
</div>
</template>
<style scoped>
.box{
display: flex;
gap:3px;
text-align: center;
justify-content: center;
flex-direction: column;
font-size: x-large;
margin-left: 450px;
margin-top: 5px;
padding: 35px;
}
</style>
利用前面學過的 v-for
來動態渲染 slot
name
ref:
https://zh-hk.vuejs.org/guide/components/slots.html