Для того щоб нормально реалізувати анімацію переходів між сторінками з Slide Left Right transition вам потрібно виконати декілька кроків.
Як я пропоную це реалізувати, без додаткових записів в router.js, без додаткових міток на сторінках, все на автопілоті.
Для цього вам потрібно нормалізувати ваш файл router.js, а саме правельно простроїти порядок маршрутів. Тобто у нас є сторінка припустимо головна /
, вона стоїть в списку перша, тому індекс у неї 1. Наступний роут /wallet
записаний відразу після, тому індекс у нього 2, і так далі. Коли користувач буде переходити з /wallet
на /
, то він буде переходити з індексу 2 на 1, тобто в нього буде спрацьовувати slide to left, якщо він будете переходити з 1 на 2, то slide to right. Якщо у роута є вкладеності, то там логіка така сама, але верхній індекс буде завжди меньший, тому перехід з вкладиних роутів буде завжди назад. Приклад файла router.js
:
import { createRouter, createWebHistory } from 'vue-router'
import routes from "@/router/routes"
let globalIndex = 1;
const mapIndex = (routes, level = 1) => {
routes.forEach(el => {
el.meta = el.meta || {};
el.meta.index = globalIndex++;
if (el.children) mapIndex(el.children, level + 1);
});
}
mapIndex(routes)
const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
routes
})
export default router
На прикладі ми визначаємо індекси усіх роутів, а вже тільки потім регіструємо їх в дадатку. Тобто всі роути отримаються свій індекс, який потім ми будемо читати при переходах для визначення типу анімації..
Якщо ви не зрозуміли що в routes.js, то там все класично без додатків:
export default [
{
path: '/',
children: [
{
path: '',
name: 'home',
component: () => import('@/views/index.vue')
},
{
path: 'upgrades',
name: 'upgrades',
component: () => import('@/views/upgrades.vue')
},
// ...
Тепер в App.vue нам потрібно считати задані мета індекси, і виходячи з них застосувати потрібну анімацію:
router.afterEach((to, from) => {
window.scrollTo({ top: 0, behavior: "smooth" })
transitionName.value = to.meta.index > from.meta.index ? 'slide-left' : 'slide-right';
})
Чудово, якщо ви все зробили правельно, то визначення напрямку буде працювати корректно.
Тепер додамо анімацію в наш App.vue
:
<template lang="pug">
.g
RouterView(v-slot="{ Component }")
transition(:name="transitionName" )
component(:is="Component")
</template >
<script setup>
const router = useRouter()
const transitionName = ref('default')
router.afterEach((to, from) => {
window.scrollTo({ top: 0, behavior: "smooth" })
transitionName.value = to.meta.index > from.meta.index ? 'slide-left' : 'slide-right';
})
</script>
<style lang="stylus">
.slide-right-enter-active, .slide-right-leave-active, .slide-left-enter-active, .slide-left-leave-active
transition: all 0.25s ease;
position fixed
top 0
width 100%
left 0
.slide-left-leave-to
opacity: 0;
transform translateX(-100%)
.slide-left-enter-from
opacity: 0;
transform translateX(100%)
.slide-right-leave-to
opacity: 0;
transform translateX(100%)
.slide-right-enter-from
opacity: 0;
transform translateX(-100%)
</style>
Зверніть увагу, що в мене в момент transition, сторінка переходить в position fixed, ви це можете выдмінити, змінив ти анімації на out-in. Але для мене потрібно було саме так. На цьому все, дякую за увагу.