我在 Vue3 和 Nuxt3 项目中创建了一个 Accordion 组件。一切都很好,除了我无法在手风琴面板的高度上放置动画。当我隐藏此手风琴的面板时,我希望能够顺利移除。
这是手风琴面板:
const panels = [
{id:1,title:'Test Accordion 1',icon:'',},
{id:2,title:'Test Accordion 2',icon:'',},
{id:3,title:'Test Accordion 3',icon:'',},
]
以及我使用该组件的地方,例如:
<accordion :panels="panels">
<template #1>
this is one
</template>
<template #2>
this is two
</template>
<template #3>
this is three
</template>
</accordion>
这是 SFC 文件:
<script setup lang="ts">
const props = defineProps({
panels: {type: Array,},
})
const current = ref(1)
function toggleAccardion(index: any) {
if (current.value == index) {
current.value = 0
return
}
current.value = index
}
</script>
<template>
<div v-for="panel in panels" :key="panel.id">
<div class="d-flex flex-row p-4 cursor-pointer bg-gray-200" @click.prevent="toggleAccardion(panel.id)">
<div v-if="panel.icon">
{{ panel.icon }}
</div>
<div class="flex-grow-1">
<h4 class="mb-0">{{ panel.title }}</h4>
</div>
<div>
<i v-if="panel.id === current" class="ki-outline ki-minus fs-4 text-gray-800"></i>
<i v-else class="ki-outline ki-plus fs-4 text-gray-800"></i>
</div>
</div>
<div class="p-4" v-if="panel.id === current">
<slot :name="panel.id"></slot>
</div>
</div>
</template>
您可以使用
<transition>
组件,在这种情况下它可以按预期工作。请查看此处了解更多信息。
首先,用
<Transition>
组件包装你的内容(面板),如下所示:
<Transition>
<div class="p-4" v-if="panel.id === current">
<slot :name="panel.id"></slot>
</div>
</Transition>
为过渡组件设置名称属性:
<Transition name="accordion">
。
现在您可以创建与 Transition
名称完全相同的自定义动画。
@keyframes accordion {
0% {
max-height: 0;
}
100% {
max-height: 200px; // max possible value
}
}
.accordion-enter-active {
animation: accordion 0.2s linear;
}
.accordion-leave-active {
animation: accordion 0.2s linear reverse;
}
为
max-height
设置面板的最大可能高度,因为我们无法使用 height:auto
或百分比值制作动画
好吧,如果你尝试这个,它看起来就会有问题。因为该面板还有一些填充。所以我们应该为该动画添加填充。更新
@keyframe
如下:
@keyframes accordion {
0% {
max-height: 0;
padding: 0 16px; // horizontal padding should not be animated
}
100% {
max-height: 200px;
padding: 16px;
}
}
越准确
max-height
,动画越流畅。