Skip to main content

Визначення маршрутів

Перш за все, коли ми запускаємо програму Techno4, ми повинні передати маршрути за замовчуванням за допомогою параметра масиву routes:
var app = new Techno4({
  routes: [
    {
      name: 'about',
      path: '/about/',
      url: './pages/about.html',
    },
    {
      name: 'news',
      path: '/news/',
      url: './pages/news.html',
      options: {
        animate: false,
      },
    },
    {
      name: 'users',
      path: '/users/',
      componentUrl: './pages/users.html',
      options: {
        props: {
          users: ['John Doe', 'Vladimir Kharlampidi', 'Timo Ernst'],
        },
      },
      on: {
        pageAfterIn: function test (e, page) {
          // do something after page gets into the view
        },
        pageInit: function (e, page) {
          // do something when page initialized
        },
      }
    },
    // Default route, match to all pages (e.g. 404 page)
    {
      path: '(.*)',
      url: './pages/404.html',
    },
  ],
});
Маршрути, визначені під час запуску програми, є маршрутами за замовчуванням, вони будуть доступні для будь-якого перегляду/маршрутизатора в програмі.

Якщо у вас є програма з декількома представленнями/маршрутизаторами, і ви хочете, щоб певний перегляд/маршрутизатор мав власні строгі маршрути, і не хочете, щоб маршрути за замовчуванням були доступні в цьому перегляді, тоді ви можете вказати той самий параметр routes в View init:

var view1 = app.views.create('.view-1', {
  routes: [
    {
      path: '/users/',
      url: './pages/users.html',
    },
    {
      path: '/user/',
      url: './pages/user.html',
    },
  ],
});
Якщо у вас є програма з кількома представленнями/маршрутизаторами, і ви хочете, щоб деякий View/Router мав додаткові маршрути, і не хочете, щоб ці додаткові маршрути були доступні в інших Views, тоді ви можете вказати параметр routesAdd в View init:
// This view will support all global routes + own additional routes
var view2 = app.views.create('.view-2', {
  // These routes are only available in this view
  routesAdd: [
    {
      path: '/blog/',
      url: './pages/blog.html',
    },
    {
      path: '/post/',
      url: './pages/post.html',
    },
  ],
})

Властивості маршруту

Добре, тепер з'ясуємо, що означає кожна властивість маршруту:
ПараметрОписТип
name
Назва маршруту, напр. HOME
string
path
Шлях маршруту. Означає, що цей маршрут буде завантажено, коли ми натиснемо посилання, яке відповідає цьому шляху, або може бути завантажено цим шляхом за допомогою API
string
options
Об'єкт з додатковими параметрами маршруту (опціонально)
object
routes
Масив із вкладеними маршрутами
array
viewName
Назва перегляду, де цей маршрут буде примусово завантажуватися
string

Master Detail

ПараметрОписТип
master
Вмикає цей маршрут як головний. Це також може бути метод, який отримує екземпляри програми та маршрутизатора, у цьому методі ви повинні повернути true або false:
boolean ; function(app, router)
{
  url: '/some-page/',
  master(app) {
    if (app.device.desktop) return true;
    return false;
  }
}

ПараметрОписТип
detailRoutes
Масив з детальними маршрутами
array

Відкладені модулі

ПараметрОписТип
modules
Масив із відкладеними модулями для завантаження перед завантаженням маршруту
array

Властивості, пов’язані з вмістом

Наступні властивості маршруту визначають, як (звідки/що) має завантажуватися вміст
ПараметрОписТип
el
Завантажити сторінку з DOM за допомогою переданого елемента HTML. Можна використовувати лише з увімкненими stackPages у View.
HTMLElement
pageName
Завантажити сторінку з DOM, яка має той самий атрибут імені даних. Можна використовувати лише з увімкненими stackPages у View.
string
content
Створює динамічну сторінку з указаного рядка вмісту
string
component
Завантажити сторінку з переданого компонента маршрутизатора Techno4
object
componentUrl
завантаження сторінки як компонента через Ajax Також підтримує динамічні параметри маршруту зі шляху маршруту за допомогою виразу {{paramName}}
string
async
Виконайте необхідні асинхронні маніпуляції та поверніть необхідний вміст і параметри маршруту. Як аргумент він отримує об'єкт контексту зворотного виклику маршруту.
function(context)

ПараметрОписТип
url
Завантажити вміст сторінки через Ajax.

Також підтримує динамічні параметри маршруту зі шляху маршруту за допомогою виразу {{paramName}}, наприклад

string
{
  path: '/users/:userId/posts/:postId',
  url: 'http://myapp.com/posts/{{userId}}/{{postId}}'
}

ПараметрОписТип
asyncComponent
Метод має повертати Promise, розв’язане за допомогою компонента або модуля ES із властивістю .default, що містить компонент.

Здебільшого він розроблений як коротша версія async для динамічного імпорту компонентів. Наприклад:

function()
{
  path: '/some-page/',
  asyncComponent: () => import('./path/to/some-page.js'),
}

Маршрутизовані вкладки

ПараметрОписТип
tabs
Масив із вкладками маршрутів
array

Маршрутизовані модалі

ПараметрОписТип
actions
Аркуш дій маршруту
object
popup
Спливаючий маршрут
object
loginScreen
Маршрут екрана входу
object
popover
Маршрут елемента popover
object
sheet
Листовий маршрут
object

Маршрутні панелі

ПараметрОписТип
panel
Панельний шлях
object

Події

ПараметрОписТип
on
Об'єкт з обробниками подій
object

Псевдоніми і перенаправлення

ПараметрОписТип
alias
Псевдонім маршруту або масив із псевдонімами маршруту. Нам потрібно вказати тут шлях псевдоніма
string, array
redirect
Перенаправлення маршруту. Нам потрібно вказати тут URL-адресу перенаправлення (а не шлях). Якщо метод, то як аргумент він отримує об’єкт контексту зворотного виклику маршруту.
string, function(context)

Перед входом/виходом

ПараметрОписТип
beforeEnter
Функція (або масив функцій), яка буде виконана перед завантаженням/введенням маршруту. Щоб продовжити завантаження маршруту, необхідно викликати дозвіл. У випадку масиву> кожна функція в масиві має бути дозволена для продовження. Якщо метод, то як аргумент він отримує об’єкт контексту зворотного виклику маршруту.
function(context), array
beforeLeave
Функція (або масив функцій), яка буде виконана перед вивантаженням/залишенням маршруту. Щоб продовжити навігацію, потрібно викликати дозвіл. У випадку масиву кожна функція в масиві має бути дозволена для продовження. Якщо метод, то як аргумент він отримує об’єкт контексту зворотного виклику маршруту.
function(context), array

keepAlive

ПараметрОписТип
keepAlive
Вмикає так званий маршрут KeepAlive. Якщо ввімкнено, завантажена сторінка та її компонент (компонент Vue, React або Router) ніколи не будуть знищені. Натомість його буде від’єднано від DOM і повторно використано за потреби.
boolean
Ось приклад більшості можливих варіантів:
routes: [
  // Load via Ajax
  {
    path: '/about/',
    url: './pages/about.html',
  },
  // Dynamic page from content
  {
    path: '/news/',
    content: `
      <div class="page">
        <div class="page-content">
          <div class="block">
            <p>This page created dynamically</p>
          </div>
        </div>
      </div>
    `,
  },
  // By page name (data-name="services") presented in DOM
  {
    path: '/services/',
    pageName: 'services',
  },
  // By page HTMLElement
  {
    path: '/contacts/',
    el: document.querySelector('.page[data-name="contacts"]'),
  },
  // By component
  {
    path: '/posts/',
    component: {
      // look below
    },
  },
  // By component url
  {
    path: '/post/:id/',
    componentUrl: './pages/component.html',
  },
  // Async
  {
    path: '/something/',
    async: function ({ app, to, resolve }) {
      // Requested route
      console.log(to);
      // Get external data and return page content
      app.request.json('http://some-endpoint/').then(function (res) {
        resolve(
          // How and what to load
          {
            content: `<div class="page">${res.data.users}</div>`
          },
        );
      });
    }
  }
],

Шлях маршруту

Як зазначено вище, властивість шляху маршруту означає шлях/URL-адресу, яка відображатиметься в адресному рядку вікна веб-переглядача (якщо ввімкнено історію браузера), коли наступний маршрут буде завантажено за допомогою API або клацання посилання з тим самим шляхом.

Також є підтримка динамічних шляхів. Отже, якщо у вашому маршруті є такий шлях /blog/users/:userId/posts/:postId/ і ви натиснете на посилання з /blog/users/12/posts/25, то на завантаженій сторінці ми отримаємо доступ до маршруту route.params, що містить { userId: 12, postId: 25 }

Зіставлення шляху маршруту обробляється бібліотекою Path To Regexp, тому все, що підтримується там, також підтримується у Techno4. Наприклад, якщо ви хочете додати маршрут за замовчуванням, який відповідає всім шляхам, ми можемо використати регулярний вираз, наприклад:

// Default route, match to all pages (e.g. 404 page)
{
  path: '(.*)',
  url: './pages/404.html',

Параметри маршруту

Давайте розглянемо додаткові параметри маршруту, які можна передати у властивості options:
ПараметрОписТип
animate
Чи повинна сторінка бути анімованою, чи ні (перезаписує налаштування маршрутизатора за замовчуванням)
boolean
history
Чи слід зберігати сторінку в історії маршрутизатора
boolean
browserHistory
Чи слід зберігати сторінку в стані браузера. Якщо ви використовуєте історію браузера, ви можете передати тут false, щоб запобігти потраплянню маршруту в історію браузера
boolean
reloadCurrent
Замінити поточну сторінку новою з маршруту, у цьому випадку анімації не буде
boolean
reloadPrevious
Замінити попередню сторінку в історії на нову з маршруту
boolean
reloadAll
Завантажити нову сторінку та видалити всі попередні сторінки з історії та DOM
boolean
clearPreviousHistory
Історія попередніх сторінок буде очищена після перезавантаження/навігації за вказаним маршрутом
boolean
ignoreCache
Якщо встановлено значення true, тоді він ігноруватиме наявність такої URL-адреси в кеші та знову завантажуватиме його за допомогою XHR
boolean
force
Якщо встановлено значення true, попередня сторінка в історії ігноруватиметься та завантажуватиметься зазначена
boolean
props
Реквізити, які будуть передані як реквізити компонента сторінки Vue/React
object
transition
Ім'я переходу на користувацьку сторінку
string
openIn
Дозволяє відкрити маршрут сторінки як модальний або панельний. Таким чином, це може бути одне з наступного: спливаюче вікно, спливне вікно, екран входу, аркуш, панель
string

Контекст зворотного виклику на маршруті

Формат зворотного виклику контексту маршруту, який використовується у властивостях маршруту async, redirect, beforeEnter і beforeLeave:
Властивість Опис
app
Посилання на глобальний екземпляр програми
to
Запитуваний маршрут
from
Наразі активний маршрут
router
Поточний екземпляр маршрутизатора
resolve
Метод виклику для вирішення/продовження маршрутизації
reject
Метод виклику для запобігання/відхилення маршрутизації
direction
Напрям навігації, може бути вперед або назад

Асинхронний маршрут

async Властивість маршруту є дуже потужним інструментом, призначеним для повернення динамічних властивостей маршруту. Це функція з такими аргументами:

async(context) ● context - контекст зворотного виклику маршруту

resolve Метод зворотного виклику маршруту має такий формат:

resolve(parameters, options)

● parameters object - об'єкт із дозволеним вмістом маршруту. Має містити одну з властивостей url, content, component або componentUrl

● options object - об'єкт із параметрами маршруту

reject функція зворотного виклику не має аргументів:

reject()

Зауважте, що поки ви не викличете resolve або reject в асинхронному методі, маршрутизація буде заблокована!

Наприклад:
routes = [
  {
    path: '/foo/',
    async({ resolve, reject }) {
      if (userIsLoggedIn) {
        resolve({ url: 'secured.html' })
      } else {
        resolve({ url: 'login.html' })
      }
    }
  }
]

Події маршруту

Можна додати всі події сторінки всередині маршруту для цієї сторінки за допомогою властивості on маршруту. Наприклад:
var app = new Techno4({
  routes: [
    // ...
    {
      path: '/users/',
      url: './pages/users.html',
      on: {
        pageBeforeIn: function (event, page) {
          // do something before page gets into the view
        },
        pageAfterIn: function (event, page) {
          // do something after page gets into the view
        },
        pageInit: function (event, page) {
          // do something when page initialized
        },
        pageBeforeRemove: function (event, page) {
          // do something before page gets removed from DOM
        },
      }
    },
    // ...
  ],
});
Зауважте, що такі події маршруту насправді є подіями DOM, тому кожен такий обробник прийматиме подію як перший аргумент із самою подією та сторінку як другий аргумент із даними сторінки. Крім того, контекст такого обробника подій (this) вказуватиме на відповідний екземпляр Router.

Вкладені маршрути

Також можна мати вкладені маршрути (маршрути в маршрутах):
routes = [
  {
    path: '/faq/',
    url: './pages/faq.html',
  },
  {
    path: '/catalog/',
    url: './pages/catalog.html',
    routes: [
      {
        path: 'computers/',
        url: './pages/computers.html',
      },
      {
        path: 'monitors/',
        url: './pages/monitors.html',
      },
      ...
    ],
  }
];
Що це означає? Для кращого розуміння насправді (під капотом) такі маршрути будуть об’єднані в наступні:
routes = [
  {
    path: '/faq/',
    url: './pages/faq.html',
  },
  {
    path: '/catalog/',
    url: './pages/catalog.html',
  }
  {
    path: '/catalog/computers/',
    url: './pages/computers.html',
  },
  {
    path: '/catalog/monitors/',
    url: './pages/monitors.html',
  },
];
Отже, припустимо, що ми знаходимося на сторінці /catalog/ і маємо такі посилання:
1.<ahref="computers/">Computers</a> - працюватиме, як очікувалося. Посилання буде об’єднано з поточним маршрутом (/catalog/ + computers/) і матимемо/catalog/computers/ які ми маємо на наших маршрутах.

2.<a href="/./computers/">Computers</a> - працюватиме, так само як у випадку 1, оскільки ./ на початку шляху означає той самий підрівень.

3.<a href="/catalog/computers/">Computers</a> - також працюватиме належним чином, як і випадок 1, оскільки / (коса риска) на початку означає корінь. І ми маємо такий кореневий маршрут у об’єднаних маршрутах.

4.<a href="/computers/">Computers</a> - не працюватиме належним чином, оскільки / (коса риска) на початку означає корінь. І в наших маршрутах немає такого кореневого маршруту /computers/

Детальні маршрути

Для представлення Master Detail також можна вказати detailRoutes на додаток до master: true для головного маршруту.

Якщо вказано detailRoutes, перехід до детального маршруту також попередньо завантажить його основний маршрут.

Але на відміну від вкладених маршрутів (зазначених у параметрах маршрутів), шляхи детальних маршрутів не об’єднуються з основним шляхом маршруту.

routes = [
  {
    path: '/blog/',
    url: './news.html',
    master: true,
    detailRoutes: [
      {
        /* We need to specify detail route path from root */
        path: '/blog/:postId/',
        url: './post.html',
      },
    ],
  },
  // ...
]

Маршрутизовані вкладки

Що означають маршрутизовані вкладки і чому це добре?

● По-перше, це надає можливість переходу до вкладок за звичайними посиланнями замість так званих спеціальних вкладок-посилань.

● По-друге, під час навігації таким маршрутом ви можете завантажити сторінку з відкритою потрібною вкладкою.

● По-третє, якщо ввімкнути історію веб-переглядача, під час переходу назад і вперед в історії відкриватиметься та сама вкладка.

● І останнє, але не менш важливе: під час використання маршрутизованих вкладок ви можете завантажувати вміст вкладок тими самими способами, що й для сторінок, тобто за допомогою url, content, component або componentUrl

Перш за все нам потрібно вказати маршрути вкладок у маршрутах програми. Припустімо, що у нас є сторінка з маршрутизованими вкладками на маршруті /tabs/:
routes = [
  {
    path: '/about-me/',
    url: './pages/about-me/index.html',
    // Pass "tabs" property to route
    tabs: [
      // First (default) tab has the same url as the page itself
      {
        path: '/',
        id: 'about',
        // Fill this tab content from content string
        content: `
          <div class="block">
            <h3>About Me</h3>
            <p>...</p>
          </div>
        `
      },
      // Second tab
      {
        path: '/contacts/',
        id: 'contacts',
        // Fill this tab content via Ajax request
        url: './pages/about-me/contacts.html',
      },
      // Third tab
      {
        path: '/cv/',
        id: 'cv',
        // Load this tab content as a component via Ajax request
        componentUrl: './pages/about-me/cv.html',
      },
    ],
  }
]
Наприклад, на сторінці /about-me/ ми можемо мати таку структуру:
<div class="page">
  <div class="navbar">
    <div class="navbar-bg"></div>
    <div class="navbar-inner">
      <div class="title">About Me</div>
    </div>
  </div>
  <div class="toolbar tabbar toolbar-bottom">
    <div class="toolbar-inner">
      <a href="./" class="tab-link" data-route-tab-id="about">About</a>
      <a href="./contacts/" class="tab-link" data-route-tab-id="contacts">>Contacts</a>
      <a href="./cv/" class="tab-link" data-route-tab-id="cv">>CV</a>
    </div>
  </div>
  <div class="tabs tabs-routable">
    <div class="tab page-content" id="about"></div>
    <div class="tab page-content" id="contacts"></div>
    <div class="tab page-content" id="cv"></div>
  </div>
</div>
Майже так само, як і зі звичайними вкладками, але з тією різницею, що більше немає класів tab-link-active і tab-active для посилань і вкладок. Ці класи та вкладки будуть перемикатися маршрутизатором. І є новий атрибут data-route-tab-id, він потрібен для перемикача вкладок, щоб зрозуміти, яке посилання стосується вибраного маршруту.

Ви можете дізнатися більше про Routable Tabs та їхні додаткові події у відповідних розділах сторінки компонента Tabs.

Маршрутизовані модалі

Модалі також можна маршрутизувати. Тут під модалями ми маємо на увазі наступні компоненти: спливаюче вікно, спливне вікно, аркуш дій, екран входу, модальний аркуш. Ймовірно, Popup і Login Screen мають більше випадків використання тут.
І ті ж функції, що й для маршрутизованих вкладок і сторінок:

● він надає можливість відкривати модали за звичайними посиланнями замість так званих спеціальних посилань або API,

● з увімкненою історією веб-переглядача той самий режим відкриватиметься, коли ви оновлюватимете веб-переглядач, переходите назад і вперед в історії,

● за допомогою маршрутизованих модалів ви можете завантажувати сам модал та його вміст так само, як і для сторінок, тобто за допомогою url, content, component або componentUrl

І ті ж функції, що й для маршрутизованих вкладок і сторінок:

● він надає можливість відкривати модали за звичайними посиланнями замість так званих спеціальних посилань або API,

● з увімкненою історією веб-переглядача той самий режим відкриватиметься, коли ви оновлюватимете веб-переглядач, переходите назад і вперед в історії,

● за допомогою маршрутизованих модалів ви можете завантажувати сам модал та його вміст так само, як і для сторінок, тобто за допомогою url, content, component або componentUrl

routes = [
  ...
  // Creates popup from passed HTML string
  {
    path: '/popup-content/',
    popup: {
      content: `
        <div class="popup">
          <div class="view">
            <div class="page">
              ...
            </div>
          </div>
        </div>
      `
    }
  },
  // Load Login Screen from file via Ajax
  {
    path: '/login-screen-ajax/',
    loginScreen: {
      url: './login-screen.html',
      /* login-screen.html contains:
        <div class="login-screen">
          <div class="view">
            <div class="page">
              ...
            </div>
          </div>
        </div>
      */
    },
  },
  // Load Popup from component file
  {
    path: '/popup-component/',
    loginScreen: {
      componentUrl: './popup-component.html',
      /* popup-component.html contains:
        <template>
          <div class="popup-screen">
            <div class="view">
              <div class="page">
                ...
              </div>
            </div>
          </div>
        </template>
        <style>...</style>
        <script>...</script>
      */
    },
  },
  // Use async route to check if the user is logged in:
  {
    path: '/secured-content/',
    async({ resolve }) {
      if (userIsLoggedIn) {
        resolve({
          url: 'secured-page.html',
        });
      } else {
        resolve({
          loginScreen: {
            url: 'login-screen.html'
          } ,
        });
      }
    },
  }
]
Відповідно до прикладу вище:

● коли ви натискаєте посилання з атрибутом href /popup-content/ , відкриється спливаюче вікно з указаним вмістом рядка,

● коли ви натискаєте посилання з атрибутом href /login-screen-ajax/ , він виконує запит Ajax до файлу login-screen.html і відкриває його як екран входу,

● коли ви натискаєте посилання з атрибутом href /popup-component/ , він виконає запит Ajax до файлу popup-component.html, розбере його як компонент маршрутизатора та відкриє як спливаюче вікно,

● коли ви натискаєте посилання з атрибутом /secured-content/ href, завантажується сторінка з secured-page.html, якщо користувач увійшов у систему, або відкривається екран входу з файлу login-screen.html, якщо користувач не ввійшов у систему.

Маршрутизовані панелі

Панелі (бічні панелі) також можуть бути маршрутизованими з тими ж функціями, що й для маршрутизованих модалів і сторінок:

● надає можливість відкривати Panel за звичайними посиланнями замість так званих спеціальних посилань або API,

● з увімкненою історією веб-переглядача та сама панель буде відкрита, коли ви оновите веб-переглядач, переміщуєтеся назад і вперед в історії,

● за допомогою маршрутизованих панелей ви можете завантажувати саму панель та її вміст у такий самий спосіб, як і для сторінок і модалів, тобто за допомогою url, content, component або componentUrl

routes = [
  ...
  // Creates Panel from passed HTML string
  {
    path: '/left-panel/',
    panel: {
      content: `
        <div class="panel panel-left panel-cover">
          <div class="view">
            <div class="page">
              ...
            </div>
          </div>
        </div>
      `
    }
  },
  // Load Panel from file via Ajax
  {
    path: '/right-panel-ajax/',
    panel: {
      url: './right-panel.html',
      /* right-panel.html contains:
      <div class="panel panel-right panel-reveal">
        <div class="view">
          <div class="page">
            ...
          </div>
        </div>
      </div>
      */
    },
  },
  // Load Panel from component file
  {
    path: '/panel-component/',
    panel: {
      componentUrl: './panel-component.html',
      /* panel-component.html contains:
      <template>
        <div class="panel panel-left panel-cover">
          <div class="view">
            <div class="page">
              ...
            </div>
          </div>
        </div>
      </template>
      <style>...</style>
      <script>...</script>
      */
    },
  },
]
Відповідно до прикладу вище:

● коли ви натискаєте посилання з атрибутом /left-panel/ href, відкриється панель із вказаного вмісту рядка,

● коли ви натискаєте посилання з атрибутом /right-panel-ajax/ href, він виконає запит Ajax до файлу right-panel.html і відкриє його як праву панель,

● коли ви натискаєте посилання з атрибутом /panel-component/ href, він виконає запит Ajax до файлу panel-component.html, розбере його як компонент маршрутизатора та відкриє як панель,

Зауважте, що маршрутизовані панелі не можна змішувати зі статичними панелями. Отже, якщо у програмі є статична ліва панель, то лише праву панель можна завантажити як маршрутизовану панель.

Маршрут перед входом/виходом

Хуки маршрутів beforeEnter і beforeLeave можуть бути дуже корисними, якщо вам потрібно виконати додаткові перевірки, виконати додаткові дії або завантажити/надіслати щось перед завантаженням маршруту (введення) і вивантаження (виходу). Це може бути один метод або масив методів для виконання. Наприклад:
routes = [
  {
    path: 'profile',
    url: 'profile.html',
    beforeEnter: function ({ resolve, reject }) {
      if (/* some condition to check user is logged in */) {
        resolve();
      } else {
        // don't allow to visit this page for unauthenticated users
        reject();
      }
    },

  },
  {
    path: 'profile-edit',
    url: 'profile-edit.html',
    beforeLeave: function ({ resolve, reject }) {
      if (/* user didn't save edited form */) {
        app.dialog.confirm(
          'Are you sure you want to leave this page without saving data?',
          function () {
            // proceed navigation
            resolve();
          },
          function () {
            // stay on page
            reject();
          }
        )
      } else {
        resolve();
      }
    }
  }
]
І, звичайно, підтримуються кілька хуків, які передаються як масив функцій:
function checkAuth({ to, from, resolve, reject }) {
  if (/* some condition to check user is logged in */) {
    resolve();
  } else {
    reject();
  }
}
function checkPermission({ to, from, resolve, reject }) {
  if (/* some condition to check user edit permission */) {
    resolve();
  } else {
    reject();
  }
}

routes = [
  {
    path: '/profile/',
    url: 'profile.html',
    // check if the user is logged in
    beforeEnter: checkAuth,
  },
  {
    path: '/profile-edit/',
    url: 'profile-edit.html',
    // check if the user is logged in and has required permission
    beforeEnter: [checkAuth, checkPermission],
  }
]

Перенаправлення та псевдонім

Псевдонім

Ми можемо передати псевдонім маршруту за допомогою властивості alias маршруту. Псевдонім у цьому випадку означає, що той самий маршрут може мати декілька шляхів доступу:
routes = [
  {
    path: '/foo/',
    url: 'somepage.html',
    alias: '/bar/',
  },
  {
    path: '/foo2/',
    url: 'anotherpage.html',
    alias: ['/bar2/', '/baz/', '/baz2/'],
  }
]
Відповідно до прикладу вище:

● якщо ми запитуємо сторінку за URL-адресою /foo/ або /bar/, перший маршрут буде відповідати, і ми отримаємо сторінку, завантажену з somepage.html

● якщо ми запитуємо сторінку за URL-адресою /foo2/ , /bar2/, /baz/, /baz2/, другий маршрут буде збігатися, і ми завантажуємо сторінку з anotherpage.html

Перенаправлення

Ми можемо передати перенаправлення маршруту за допомогою властивості redirect: якщо ми передаємо redirect як string, ми повинні передати тут URL-адресу прямого перенаправлення якщо ми передаємо redirect як function , нам потрібно викликати параметр resolve функції з URL-адресою перенаправлення

Наприклад:

routes = [
  {
    path: '/foo/',
    url: 'somepage.html',
  },
  {
    path: '/bar/',
    redirect: '/foo/',
  },
  {
    path: '/baz/',
    redirect: function ({to, resolve, reject}) {
      // if we have "user" query parameter
      if (to.query.user) {
        // redirect to such url
        resolve('/foo/?user=' + to.query.user);
      }
      // otherwise do nothing
      else reject();
    }
  }
]
Наведений вище приклад означає:

● коли ми запитуємо URL-адресу /bar/, маршрутизатор перенаправлятиме на URL-адресу /foo/, а потім шукатиме маршрут, який відповідає цій новій URL-адресі. У цьому випадку він відповідатиме першому маршруту зі шляхом /foo/ і завантажуватиме сторінку з somepage.html

● коли ми запитуємо /baz/?user=john, ми перенаправляємо на URL /foo/?user=john, який відповідатиме першому маршруту

● коли ми запитуємо /baz/ (без запиту), нічого не станеться

Зауважте, що під час перенаправлення ми передаємо URL-адресу, а не шлях маршруту, як у псевдонімі

Keep Alive

Якщо функцію KeepAlive увімкнено, як тільки маршрутизатор завантажить таку сторінку, сторінка та, якщо це можливо, її компонент (компонент Vue, React або Router) ніколи не буде знищено. Натомість його буде від’єднано від DOM і повторно використано за потреби.

Це може бути корисно ввімкнути для «важких» сторінок, які не надто часто оновлюються. Наприклад, сторінка з картою або з важким полотном чи іншим обчисленням. За звичайною логікою всі ці важкі обчислення відбуватимуться кожного разу, коли відвідуватиме цю сторінку. Але з keepAlive це буде зроблено один раз, і під час усіх наступних відвідувань маршрутизатор повторно використовуватиме вже відрендерений елемент DOM сторінки.

Це також може бути корисним, якщо вам дійсно потрібно зберегти стан сторінки. Якщо функцію KeepAlive увімкнено, сторінка буде завантажена наступного разу, усі модифікації DOM і стан елементів форми буде збережено.

Але є речі, на які варто звернути увагу:

● Він не підтримується для асинхронних маршрутів

● Він підтримується лише для сторінок (не для панелей і модальних елементів)

● Якщо у вас є динамічний шлях маршруту (наприклад, /some-page/:foo/:bar) або ви покладаєтеся на запит маршруту сторінки (?foo=bar), тоді параметри запиту та маршруту не будуть змінені після початкового завантаження.

● page:beforeremove,pageBeforeRemove події сторінки ніколи не запускатимуться для такої сторінки

● Якщо ви використовуєте його як компонент Vue, то beforeDestroy знищені хуки ніколи не запускатимуться для такого компонента. created, mounted гаки спрацюють лише один раз.

● Якщо ви використовуєте його як компонент React, метод componentWillUnmount ніколи не запускатиметься для такого компонента. Методи componentWillMount, componentDidMount запускатимуться лише один раз.

● Якщо ви використовуєте його як компонент T4 Router, то beforeDestroy знищені хуки ніколи не запускатимуться для такого компонента. created, mounted гаки спрацюють лише один раз.

Щоб уникнути пасток із життєвим циклом компонентів і сторінок, рекомендуємо покладатися на такі події сторінки:

● page:mounted - буде завжди викликано для сторінки маршруту keepAlive, коли її елемент DOM приєднано або повторно приєднано.

● page:beforeunmount - завжди буде викликатися для сторінки маршруту keepAlive, коли її елемент DOM буде від’єднано від DOM.

Щоб створити маршрут KeepAlive, нам просто потрібно передати його параметрам KeepAlive: true :

import SomPageComponent from './some-page.js';

var routes = [
  /* Usual route */
  {
    path: '/',
    url: './pages/home.html',
  },
  /* Alive route. Will be loaded from file first time, and then will reuse rendered DOM element */
  {
    path: '/map/',
    url: './pages/map.html',
    keepAlive: true,
  },

  /* Alive route. Will be created as component, and then will reuse rendered DOM element */
  {
    path: '/some-page/',
    component: SomPageComponent,
    keepAlive: true,
  },
];