Переходы между маршрутами

В Vue.js управление навигацией между страницами приложения осуществляется с помощью официального маршрутизатора Vue Router. Основная задача маршрутизатора — связывать URL с компонентами, обеспечивая динамическое отображение контента без перезагрузки страницы. Особое внимание уделяется переходам между маршрутами, так как они обеспечивают плавность и улучшенный пользовательский опыт.


Навигация и методы маршрутизатора

Vue Router предоставляет несколько способов перехода между маршрутами:

  1. Программная навигация через методы объекта $router:
this.$router.push({ name: 'Home' });
this.$router.replace({ path: '/about' });
  • push добавляет новый маршрут в историю браузера.
  • replace заменяет текущий маршрут, не создавая новую запись в истории.
  1. Декларативная навигация с использованием компонента <router-link>:
<router-link to="/about">О нас</router-link>
<router-link :to="{ name: 'Profile', params: { userId: 123 } }">Профиль</router-link>
  • Атрибут to поддерживает как строковый путь, так и объект с именем маршрута и параметрами.
  • <router-link> автоматически управляет активным состоянием ссылки через класс router-link-active.
  1. Методы с возвратом к предыдущему маршруту:
this.$router.go(-1); // аналог кнопки "Назад"
this.$router.go(1);  // вперед по истории

Переходы с анимацией

Vue.js тесно интегрирован с системой анимации через компонент <transition> и <transition-group>. Для маршрутов важно использовать <router-view> внутри <transition>:

<transition name="fade" mode="out-in">
  <router-view></router-view>
</transition>
  • Атрибут name задаёт базовое имя для классов CSS: .fade-enter-active, .fade-leave-active, .fade-enter, .fade-leave-to.
  • mode="out-in" гарантирует, что старый компонент полностью скрыт перед появлением нового.

CSS-пример:

.fade-enter-active, .fade-leave-active {
  transition: opacity 0.5s;
}
.fade-enter, .fade-leave-to {
  opacity: 0;
}

Эта конфигурация создаёт плавный эффект исчезновения старого компонента и появления нового при смене маршрута.


Навигационные охранники

Для контроля переходов между маршрутами применяются навигационные охранники (navigation guards). Они позволяют выполнять проверки, загружать данные или отменять переход.

Глобальные охранники:

router.beforeEach((to, from, next) => {
  if (to.meta.requiresAuth && !isAuthenticated()) {
    next({ name: 'Login' });
  } else {
    next();
  }
});
  • to — объект целевого маршрута.
  • from — объект текущего маршрута.
  • next() управляет продолжением навигации: можно разрешить, перенаправить или отменить переход.

Локальные охранники компонента:

export default {
  beforeRouteEnter(to, from, next) {
    next(vm => vm.fetchData(to.params.id));
  },
  beforeRouteUpdate(to, from, next) {
    this.fetchData(to.params.id);
    next();
  },
  beforeRouteLeave(to, from, next) {
    if (this.hasUnsavedChanges) {
      const answer = window.confirm('Сохранить изменения перед выходом?');
      if (answer) next();
      else next(false);
    } else {
      next();
    }
  }
};
  • beforeRouteEnter не имеет доступа к экземпляру компонента через this до момента монтирования.
  • beforeRouteUpdate вызывается при переходе на тот же маршрут с другими параметрами.
  • beforeRouteLeave позволяет блокировать уход с текущего маршрута при несохранённых изменениях.

Динамические параметры и переходы

Маршруты могут содержать динамические параметры, передаваемые через URL:

{
  path: '/user/:id',
  name: 'User',
  component: UserProfile
}

Переход с параметром:

this.$router.push({ name: 'User', params: { id: 42 } });

Особенности работы:

  • При переходе между маршрутами с одним компонентом, но разными параметрами, компонент не пересоздаётся, а просто обновляются параметры. Чтобы реагировать на это, используют beforeRouteUpdate или watch на $route.

Отложенная загрузка маршрутов

Для уменьшения объёма начальной загрузки можно применять динамический импорт:

const About = () => import('./components/About.vue');

const routes = [
  { path: '/about', component: About }
];
  • Компонент загружается только при переходе на соответствующий маршрут.
  • В сочетании с анимациями и навигационными охранниками это создаёт современный и отзывчивый интерфейс.

Примеры сложных сценариев переходов

  1. Переход с подтверждением выхода:
beforeRouteLeave(to, from, next) {
  if (this.formDirty) {
    next(confirm('Есть несохранённые данные. Выйти?') ? true : false);
  } else {
    next();
  }
}
  1. Переход с предварительной загрузкой данных:
beforeRouteEnter(to, from, next) {
  fetchUser(to.params.id).then(user => {
    next(vm => vm.setUser(user));
  });
}
  1. Анимация смены страниц по направлениям:
<transition :name="transitionName" mode="out-in">
  <router-view></router-view>
</transition>
watch: {
  '$route'(to, from) {
    this.transitionName = from.path.length < to.path.length ? 'slide-left' : 'slide-right';
  }
}

Понимание и правильное использование переходов между маршрутами позволяет создавать плавные, динамичные и отзывчивые веб-приложения на Vue.js, обеспечивая высокий уровень UX и масштабируемость архитектуры.