过渡元素的主要问题是你希望它们同时在 DOM 中占据相同的空间(即使从视觉上看,一个进入,一个存在 - 这只能通过
transforms
完成,但是两个元素需要占据DOM 中的相同空间)。
因此,您需要给其中之一
position:absolute
并使用 CSS 正确调整其大小和位置,以匹配没有 position:absolute
时它所具有的确切位置和大小(这是不转换时它将具有的位置和大小)。
这是一个工作示例。请注意,您可能需要将不同的样式应用于不同的元素。
由于您没有使用自己的标记提供最小的、可重现的示例,因此无法知道。
在上面的例子中,我给出了后续的
<div>
(进入的那个)
position: absolute;
width: 100%;
top: 60px;
left: 0;
如果您选择将所有
<router-view>
包装到带有 position:relative
的通用包装元素中,则 top
需要为 0
(在示例中,60px
占 <nav>
的高度)。
注意:和是,正如其他人已经指出的那样,您不需要
mode="in-out"
。但这仍然给你留下了定位问题。
编辑:我又玩了两个例子。
实际上,由于您不需要任何特殊行为并且实际上希望两种转换同时发生,因此您根本不应该使用
mode
。只需将其删除,它就应该按照您所描述的那样工作。从您粘贴的文档链接:
同时进入和离开过渡并不总是可取的,因此 Vue 提供了一些替代过渡模式
进出:新元素首先过渡,然后完成后当前元素过渡出去。
out-in:当前元素先转出,完成后新元素转入。
mode="in-out"
:新元素首先过渡,然后完成后,当前元素过渡出去。
new Vue({
el: '#app',
data: {
message: 'Hello Vue!',
showOn: true
},
methods: {
handleClick() {
console.log(this.message);
}
}
})
.slide-fade-enter-active {
transition: all .3s ease;
position: absolute;
left: 0;
top: 0;
}
.slide-fade-leave-active {
position: absolute;
left: 0;
top: 0;
}
.slide-fade-enter, .slide-fade-leave-to {
transform: translateX(10px);
opacity: 0;
}
#app {
position: relative;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<body>
<div id="app">
<transition name="slide-fade" mode="in-out">
<button v-if="showOn"
key="on"
type="button"
@click="showOn=false">On</button>
<button v-else type="button"
key="off"
@click="showOn=true">Off</button>
</transition>
</div>
</body>
我使用
position: absolute
和 transition-delay
来模仿 mode="in-out"
这样进入转换会等待,直到离开转换完成
.slide-fade-enter-active {
transition: all 0.3s ease-in-out;
transition-delay: 0.3s;
}
.slide-fade-leave-active {
position: absolute;
transition: all 0.3s ease-in-out;
}
.slide-fade-enter-from,
.slide-fade-leave-to {
transform: translateX(-15px);
opacity: 0;
}