Анімація page transition slide left right Vue3

Для того щоб нормально реалізувати анімацію переходів між сторінками з 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. Але для мене потрібно було саме так. На цьому все, дякую за увагу.