我有一个
v-card
,我想通过单击来来回制作动画。
如果我单击向左的箭头,卡片应滚动到右侧,然后立即从左侧滚动回来。另一个按钮应该以相反的方式工作。
问题是,这里什么也没发生。我做错了什么?
我的模板:
<v-card>
<v-btn icon @click="back = false">
<v-icon>mdi-arrow-left</v-icon>
</v-btn>
<v-btn icon @click="back = true">
<v-icon>mdi-arrow-right</v-icon>
</v-btn>
</v-card>
<transition :name="back ? 'slide-fade' : 'slide-fade-reverse'">
<v-card max-width="200" class="mx-auto mt-5" height="80">
<span class="d-flex justify-center pt-7">{{back}}</span>
</v-card>
</transition>
我的脚本:
data() {
return {
back: false,
}
},
我的CSS:
/* Prev */
.slide-fade-enter-active {
transition: all .3s ease;
}
.slide-fade-leave-active {
transition: all .3s ease;
}
.slide-fade-enter {
transform: translateX(100px);
opacity: 0;
}
.slide-fade-leave-to {
transform: translateX(-100px);
opacity: 0;
}
/* Next */
.slide-fade-reverse-enter-active {
transition: all .3s ease;
}
.slide-fade-reverse-leave-active {
transition: all .3s ease;
}
.slide-fade-reverse-enter {
transform: translateX(-100px);
opacity: 0;
}
.slide-fade-reverse-leave-to {
transform: translateX(100px);
opacity: 0;
}
我为此制作了一支笔:https://codepen.io/Tenarius/pen/WNwdEve
为了使
leave
和 enter
过渡起作用,<transition>
元素必须具有 v-if
条件。当它从 false
变为 true
时,元素将被插入到 DOM 中并根据 enter
转换进行动画处理。当条件从 true
变为 false
时,将执行离开转换,当结束时,该元素将从 DOM 中删除。
但是,你不具备这样的条件。您只需更新卡片内容并期望将其从 DOM 中删除并替换为新卡片。
为了实现预期的功能,您应该使用卡片列表(仅包含当前活动的卡片),并结合使用
<transition-group>
,其内部使用与 transition
相同的机制,但 v-if
条件是元素是否属于集合。
在您的情况下,“集合”将是经过过滤的卡片列表,仅包含一张卡片。通过这种技术,离开的元素将获得离开动画,而进入的元素将获得进入动画,因为根据模型的变化,元素实际上被删除并添加到 DOM 中。
在此处查看其工作原理。
// index.scss
$animation-duration: 0.15s;
.step-next-enter-active,
.step-next-leave-active,
.step-prev-enter-active,
.step-prev-leave-active {
transition:
transform #{$animation-duration} ease,
opacity #{$animation-duration} ease;
}
.step-next-enter-from,
.step-prev-leave-to {
transform: translateX(32px);
opacity: 0;
}
.step-next-leave-to,
.step-prev-enter-from {
transform: translateX(-32px);
opacity: 0;
}
.step-next-leave-from,
.step-next-enter-to,
.step-prev-leave-from,
.step-prev-enter-to {
transform: translateX(0);
}
<script setup lang="ts">
...
const animationDirection = ref<"step-next" | "step-prev">("step-next");
// Calculate the height of the current step for smooth transition
const currentStepHeight = ref<number>();
watch(
() => [store.currentStep],
([currentStep], [oldStep]) => {
if (currentStep !== oldStep) {
animationDirection.value =
currentStep > oldStep ? "step-next" : "step-prev";
}
},
{
flush: "pre",
}
);
// Get the current transitioning element height
function onEnter(e: Element): void {
const elHeight = e.getBoundingClientRect().height;
currentStepHeight.value = elHeight;
}
</script>
...
<div
class="overflow-hidden transition-all"
:style="{
height: currentStepHeight + 'px',
maxHeight: currentStepHeight + 'px',
}"
>
<Transition
:name="animationDirection"
mode="out-in"
@enter="onEnter"
>
<Component :is="steps[store.currentStep - 1]" />
</Transition>
</div>
...
</template>
希望有帮助!