在父页面下点击按钮实现当前页面下子页面的切换,用到transition组件,用法如下,另外,设置组件的position为absolute,来避免上一个页面的残留视图在切换页面动画过程中显示在下一页:
<template>
<div class="container">
<div class="page-container">
<transition
name="slide"
mode="out-in"
@before-enter="beforeEnter"
@after-leave="afterLeave"
>
<div class="page-wrapper" :key="currentIndex">
<component :is="currentComponent"></component>
</div>
</transition>
</div>
<div class="nav-buttons">
<button @click="showPrevPage">Prev</button>
<button @click="showNextPage">Next</button>
</div>
</div>
</template>
<script>
import Page1 from '@/components/Page1.vue'
import Page2 from '@/components/Page2.vue'
import Page3 from '@/components/Page3.vue'
export default {
components: {
Page1,
Page2,
Page3
},
data() {
return {
currentIndex: 0,
pages: [Page1, Page2, Page3],
isAnimating: false
}
},
computed: {
currentComponent() {
return this.pages[this.currentIndex]
}
},
methods: {
showPrevPage() {
if (this.isAnimating) return
this.isAnimating = true
this.currentIndex = (this.currentIndex - 1 + this.pages.length) % this.pages.length
},
showNextPage() {
if (this.isAnimating) return
this.isAnimating = true
this.currentIndex = (this.currentIndex + 1) % this.pages.length
},
beforeEnter(el) {
// 在动画开始前执行一些逻辑,比如刷新 DOM 元素
this.$nextTick(() => {
el.classList.add('slide-enter-active')
})
},
afterLeave(el) {
// 在动画结束后执行一些逻辑,比如重置 isAnimating 标志
this.isAnimating = false
}
}
}
</script>
<style>
.container {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 100vh;
}
.page-container {
width: 80%;
height: 80%;
position: relative;
overflow: hidden;
}
.page-wrapper {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
.slide-enter-active {
transition: all 0.5s ease;
}
.slide-enter-from {
transform: translateX(100%);
}
.slide-enter-to {
transform: translateX(0);
}
</style>