Интеграция с Vue

Page.js — это небольшая клиентская библиотека для маршрутизации на стороне браузера. Для интеграции с Vue.js необходимо сначала установить пакет через npm:

npm install page

После установки его можно импортировать в основной файл приложения, например, в main.js или app.js:

import page from 'page';

При использовании модульной структуры ES6 импорт page позволяет вызывать его методы напрямую и связывать маршруты с компонентами Vue.


Настройка маршрутов

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

Пример базовой конфигурации маршрутов:

import Home from './components/Home.vue';
import About from './components/About.vue';
import Contact from './components/Contact.vue';

const routes = [
  { path: '/', component: Home },
  { path: '/about', component: About },
  { path: '/contact', component: Contact },
];

const app = new Vue({
  el: '#app',
  data: {
    currentView: Home
  },
  render(h) {
    return h(this.currentView);
  }
});

// Привязка Page.js маршрутов
routes.forEach(route => {
  page(route.path, () => {
    app.currentView = route.component;
  });
});

page();

Здесь создаётся реактивное свойство currentView, которое хранит текущий компонент. Page.js вызывает обработчик при смене URL, обновляя currentView, что автоматически обновляет отображение компонента через механизм Vue.


Динамические параметры маршрутов

Page.js поддерживает динамические сегменты URL с двоеточием (:). Это удобно для страниц с параметрами, например, профилей пользователей.

import UserProfile from './components/UserProfile.vue';

page('/user/:id', ctx => {
  app.currentView = UserProfile;
  app.$data.userId = ctx.params.id;
});

ctx.params.id содержит значение параметра id из URL. В компоненте Vue его можно использовать для запроса данных или отображения информации.


Вложенные маршруты и middleware

Page.js позволяет создавать цепочку middleware для маршрутов. Каждый middleware получает контекст (ctx) и функцию next, которую нужно вызвать для продолжения обработки маршрута.

Пример аутентификации:

function requireAuth(ctx, next) {
  if (!app.$data.isAuthenticated) {
    page('/login');
  } else {
    next();
  }
}

page('/dashboard', requireAuth, () => {
  import('./components/Dashboard.vue').then(module => {
    app.currentView = module.default;
  });
});

Это позволяет легко реализовать защиту маршрутов, асинхронную подгрузку компонентов и любые другие предварительные действия перед отображением страницы.


Асинхронная загрузка компонентов

В Vue с Page.js часто используют ленивую загрузку компонентов через динамический импорт, что снижает размер начального бандла:

page('/settings', async () => {
  const module = await import('./components/Settings.vue');
  app.currentView = module.default;
});

Компонент загружается только при переходе на соответствующий маршрут, что улучшает производительность приложения.


Обработка ошибок маршрутизации

Page.js позволяет определить глобальные обработчики ошибок, например, для несуществующих маршрутов:

page('*', () => {
  import('./components/NotFound.vue').then(module => {
    app.currentView = module.default;
  });
});

Символ * означает “любой маршрут, который не совпал с предыдущими”. Такой подход гарантирует корректную работу страницы 404.


Интеграция с Vue Router-подобным API

Хотя Vue Router является стандартным решением для Vue, Page.js может использоваться для лёгких проектов или специфических случаев. Для большего удобства можно создать обёртку над Page.js, имитирующую Vue Router API:

const Router = {
  push(path) {
    page(path);
  },
  currentRoute: Vue.observable({ path: window.location.pathname })
};

page('*', ctx => {
  Router.currentRoute.path = ctx.path;
});

Это упрощает работу с навигацией внутри компонентов, сохраняя реактивность и согласованность состояния.


Использование с компонентами шаблонов

Для интеграции с шаблонными компонентами удобно использовать директиву v-if:

<div id="app">
  <home v-if="currentView === Home"></home>
  <about v-if="currentView === About"></about>
  <contact v-if="currentView === Contact"></contact>
</div>

Или рендер-функцию через h(this.currentView) для динамического отображения компонента, что особенно полезно при ленивой загрузке.


Управление переходами и анимациями

Page.js предоставляет хуки page.start() и page.show() для контроля переходов. В сочетании с Vue Transition можно добавлять плавные анимации при смене компонентов:

<transition name="fade">
  <component :is="currentView"></component>
</transition>
.fade-enter-active, .fade-leave-active {
  transition: opacity 0.3s;
}
.fade-enter, .fade-leave-to {
  opacity: 0;
}

Таким образом, маршрутизация через Page.js становится полностью интегрированной с реактивной системой Vue и поддерживает динамические и асинхронные сценарии.