ninelines-router
v1.0.4
Published
JavaScript router
Downloads
10
Readme
ninelines-router
Минималистичный JavaScript роутер для работы с одностраничными сайтами и приложениями (SPA).
Особенности:
- Параметризованные URL (благодаря библиотеке path-to-regexp);
- Поддержка Promise;
- Удобная работа с URL и GET-параметрами (благодаря библиотекам url-parse и querystringify);
- Именованные маршруты;
- Поддержка создания переходов для предзаданных маршрутов.
Установка
NPM
Для установки с помощью npm требуется выполнить следующую команду:
npm install --save ninelines-router
Использование
Основы
После установки роутер необходимо подключить:
import {Router} from 'ninelines-router';
И инициализировать:
let router = new Router();
При отсутствии модульной системы библиотека (
dist/ninelines-router.js
) экспортируетRouter
в глобальный объектninelines.router
:let router = new ninelines.router.Router();
Далее создаем необходимые маршруты:
router.addRoute({
path: '/',
onEnter() {
// ...
},
});
router.addRoute({
path: '/about',
onEnter() {
// ...
},
});
router.addRoute({
path: '/contacts',
onEnter() {
// ...
},
});
И в конце запускаем роутер:
router.start();
Параметризованные URL
Роутер поддерживает создание маршрутов с параметризованными URL.
router.addRoute({
path: '/article/:id',
onEnter(prevState, currentState) {
let id = currentState.params.id;
// ...
},
});
prevState
и currentState
хранят состояние сайта в различный момент времени: prevState
до перехода, currentState
после перехода.
Объект состояния имеет следующую структуру:
{
route: Route,
params: Object,
query: Object,
}
route
- инстанс маршрута, который соответствует данному состоянию илиnull
, если такого маршрута нет (например,prevState.route === null
при первом переходе на сайт);params
- объект с параметрами данного состояния;query
- объект с GET-параметрами данного состояния;
Пример:
router.addRoute({
path: '/article/:id',
onEnter(prevState, currentState) {
// При переходе по ссылке /article/42
// currentState.params === {id: '42'}
// currentState.query === {}
// При переходе по ссылке /article/42?x=10&y=4&z=8
// currentState.params === {id: '42'}
// currentState.query === {x: '10', y: '4', z: '8'}
},
});
Более подробную информацию о параметризованных URL можно найти в документации к библиотеке path-to-regexp.
Именованные маршруты
Роутер поддерживает создание именованных маршрутов:
router.addRoute({
path: '/',
name: 'home',
onEnter() {
// ...
},
});
router.addRoute({
path: '/about',
name: 'about',
onEnter() {
// ...
},
});
router.addRoute({
path: '/article/:id',
name: 'article',
onEnter(prevState, currentState) {
// ...
},
});
Переходы между страницами
Перейти на другую страницу можно следующим образом:
router.navigate('/');
router.navigate('/article/42');
// Первым параметром можно передать имя маршрута
router.navigate('article', {
params: {
id: 42,
},
});
Также имеется возможность привязать любую ссылку к роутеру, добавив атрибут data-router-link
:
<a href="/article/42" data-router-link>
Перейти на 42-ую статью
</a>
Если ссылки с атрибутом data-router-link
подгружаются динамически вместе с контентом, то требуется вручную привязать их к роутеру:
router.bindLinks();
События
Маршруты поддерживают три основные события:
beforeEnter
- срабатывает до перехода по маршруту;enter
- срабатывает после перехода по маршруту;leave
- срабатывает при покидании маршрута;
Пример:
router.addRoute({
path: '/',
onBeforeEnter(currentState, nextState) {
// ...
},
onEnter(prevState, currentState) {
// ...
},
onLeave(currentState, nextState) {
// ...
},
});
Сам роутер поддерживает следующие события:
start
- срабатывает до событияbeforeEnter
;leave
- срабатывает при покидании какого-либо маршрута;beforeEnter
- срабатывает до перехода по какому-либо маршруту;enter
- срабатывает после перехода по какому-либо маршруту;complete
- срабатывает после завершения событияenter
;notFound
- срабатывает в том случае, если подходящий маршрут не найден;
Пример:
router.on('notFound', (path) => {
// ...
});
При необходимости событие можно вызвать вручную:
router.trigger('notFound', [location.pathname]);
Использование Promise
При необходимости из любого события можно вернуть Promise
:
let pageHome = document.getElementById('page-home');
router.addRoute({
path: '/',
onEnter() {
return new Promise((resolve) => {
pageHome.classList.remove('is-hidden');
TweenMax.from(pageHome, 1, {
opacity: 0,
clearProps: 'opacity',
onComplete() {
resolve();
},
});
});
},
onLeave() {
return new Promise((resolve) => {
TweenMax.to(pageHome, 1, {
opacity: 0,
onComplete() {
pageHome.classList.add('is-hidden');
TweenMax.set(pageHome, {
clearProps: 'opacity',
});
resolve();
},
});
});
},
});
Transition
Transition
используется для обработки предзаданных переходов.
router.addRoute({
path: '/',
});
router.addRoute({
path: '/about',
});
router.addRoute({
path: '/article/:id',
name: 'article',
});
router.addRoute({
path: '/news/:year/:month/:day',
name: 'news',
});
// Переход / => /about
router.addTransition({
from: '/',
to: '/about',
onEnter() {
// ...
},
});
// Переход article => news
router.addTransition({
from: 'article',
to: 'news',
onEnter() {
// ...
},
});
Того же результата можно добиться и без Transition
:
router.addRoute({
path: '/',
});
router.addRoute({
path: '/about',
onEnter(prevState, currentState) {
if (prevState.route.path === '/') {
// ...
}
},
});
router.addRoute({
path: '/article/:id',
name: 'article',
});
router.addRoute({
path: '/news/:year/:month/:day',
name: 'news',
onEnter(prevState, currentState) {
if (prevState.route.name === 'article') {
// ...
}
},
});
Но синтаксис addTransition
проще, чем множество условий. К тому же Transition
поддерживает события beforeEnter
, enter
, leave
и предоставляет два дополнительных события:
start
- начало перехода;complete
- конец перехода;
Порядок вызова событий выглядит следующим образом:
start
leave
beforeEnter
enter
complete
router.addTransition({
from: '/',
to: '/about',
onStart(currentState, nextState) {
// ...
},
onLeave(currentState, nextState) {
// ...
},
onBeforeEnter(currentState, nextState) {
// ...
},
onEnter(prevState, currentState) {
// ...
},
onComplete(prevState, currentState) {
// ...
},
});