我正在尝试创建一个简单的 Vue 组件,通过向左滑动一个元素并同时从右侧滑动第二个元素来替换它,从而交换两个元素。再次触发时反之亦然。
我可以让内容滑出,但它似乎没有滑入,只是出现。
此外,在过渡期间,两个元素都是可见的,这会扩展父元素,并且我正在努力让它们并排滑动。
我尝试过对元素使用绝对定位,但父元素显然失去了它的高度,如果可能的话,我不想硬编码高度值。
<script setup>
import { ref } from 'vue';
const isActivated = ref(false)
</script>
<template>
<div class="p-2 relative overflow-hidden">
<Transition name="slide-left">
<div v-show="!isActivated" class="w-full">
<slot name="first-content" />
</div>
</Transition>
<Transition name="slide-right">
<div v-show="isActivated" class="w-full absolute top-0 left-0">
<slot name="second-content" />
</div>
</Transition>
<div @click.prevent.stop="isActivated = !isActivated" class="px-2 absolute top-0 right-2" >
<slot name="trigger" />
</div>
</div>
</template>
<style>
.slide-left-enter-active,
.slide-left-leave-active,
.slide-right-enter-active,
.slide-right-leave-active{
transition: all .8s;
}
.slide-left-enter-from,
.slide-left-leave-to{
transform: translateX(-100%);
opacity:0;
}
.slide-left-enter-to,
.slide-left-leave-from{
transform: translateX(0%);
opacity:100
}
.slide-right-enter-from,
.slide-right-leave-to {
transform: translateX(100%);
opacity:0;
}
.slide-right-enter-to,
.slide-right-leave-from {
transform: translateX(0%);
opacity:100;
}
</style>
您使用的是 Vue 3 转换类名称,在 Vue 2 中,
from
转换类没有 -from
后缀(请参阅 文档)。所以它必须是 .slide-left-enter
而不是 .slide-left-enter-from
,对于 slide-right
也是如此。修复类以使输入转换起作用。
解决过渡期间堆栈效果的一个简单方法是在过渡期间将其中一个元素绝对定位:
.slide-left-leave-active,
.slide-left-enter-active{
position: absolute;
}
这是一个片段:
new Vue({
template: `
<v-app>
<v-container class="w-1/4 h-15">
<div class="p-2 relative overflow-hidden border">
<Transition name="slide-left">
<div v-show="!isActivated" class="w-full">
Some text in position 1
</div>
</Transition>
<Transition name="slide-right">
<div v-show="isActivated" class="w-full">
Some other text in position 2
</div>
</Transition>
<div @click.prevent.stop="isActivated = !isActivated" class="px-2 absolute top-1 right-2" >
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" class="w-5 fill-white">
<path d="M9.5 13a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0zm0-5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0zm0-5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0z"/>
</svg>
</div>
</div>
</v-container>
</v-app>
`,
el: "#app",
vuetify: new Vuetify(),
created() {
this.$vuetify.theme.dark = true;
},
data() {
return {
isActivated: false,
}
},
});
.slide-left-enter-active,
.slide-left-leave-active,
.slide-right-enter-active,
.slide-right-leave-active{
transition: all .8s;
}
.slide-left-leave-active,
.slide-left-enter-active{
position: absolute;
}
.slide-left-leave-to,
.slide-left-enter{
transform: translateX(-100%);
opacity:0;
}
.slide-left-enter-to,
.slide-left-leave{
transform: translateX(0%);
opacity:100;
}
.slide-right-enter,
.slide-right-leave-to {
transform: translateX(100%);
opacity:0;
}
.slide-right-enter-to,
.slide-right-leave {
transform: translateX(0%);
opacity:100;
}
<link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/@mdi/[email protected]/css/materialdesignicons.min.css" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/vuetify.min.css" rel="stylesheet">
<div id="app"></div>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vuetify.js"></script>
<script src="https://cdn.tailwindcss.com"></script>