Иногда кажется, что веб компоненты не дотягивают до фреймворка, особенно если сравнивать их с наиболее популярными представителями. Но многое самое насущное, что не закрывается реализацией стандартов входящих в понятие веб компонентов, достаточно легко прикрутить с помощью библиотек или небольшого объема своего изящного кода. Одной из таких возможностей является роутинг на стороне фронтенда. Фича не всегда необходимая, возможно даже спорная, но в большинстве фреймворков она присутствует и многими используется. Что же в веб-компонентах? А мы попробуем реализовать роутинг с помощью библиотеки navigo.
Чтобы консольные команды работали лучше в ОС Windows можно установить Unix-утилиты из дистрибутива гит под эту систему, ну или видимо использовать новые возможности WSL и терминалов.
Для начала создадим проект:
и много раз нажимаем энтер пока не отпустит
затем поставим библиотеку
создадим index.html
и в нем подключим библиотеку и определим главный класс приложения, у нас он будет инкапсулировать в себе логику роутинга и управления всеми дочерними компонентами.
Веб-компоненты подарили нам возможность автовызова хука при появлении элемента в дереве, за которым закреплен наш класс, в дереве объектов браузера. В нем мы и инициализируем библиотеку роутинга кодом прямо из примера с гитхаба библиотеки (в реально жизни это стоит сделать красивее с модульной загрузкой).
Добавим обработку роутов:
При каждом изменении роута наш компонент обновляет внутреннее содержимое добавляя в него новый тег. Осталось зарегистрировать эти теги за новыми компонентами страниц.
В самом верху страницы добавим ссылки, чтобы проверить навигацию:
атрибут data-navigo позволяет нажатия по ним обрабатывать роутером, а не осуществлять запросы на бекенд. Который пора уже запустить, например вот так:
открыть в браузере 127.0.0.1:8080 или какой он вам там напишет и убедиться, что все работает.
Теперь мы можем разнести все как полагается по отдельным файлам, приделать шаблонизацию и динамическую загрузку страниц, вынести роуты в концигурацию. Веб-компоненты возьмут на себя основную работу с Жизненным Циклом объектов приложения, только эвенты надо не забывать разбиндивать в хуке disconnectedCallback()
Поскольку я хотел показать насколько быстро это все делается, растягивать дальше статью пожалуй не буду;)
Об чем-то из этого я уже писал в статьях:
Быстрый старт с WebComponents
и
WebComponents как фреймворки, взаимодействие компонентов
Ждите новых открове^Wстатей, шэрьте и лайкайте!
Получившийся исходный код можно посмотреть вот репозитории на битбакете:
https://bitbucket.org/techminded/testnavigo/
Чтобы консольные команды работали лучше в ОС Windows можно установить Unix-утилиты из дистрибутива гит под эту систему, ну или видимо использовать новые возможности WSL и терминалов.
Для начала создадим проект:
mkdir testnavigo
cd testnavigo
npm init
и много раз нажимаем энтер пока не отпустит
затем поставим библиотеку
npm i navigo --save
создадим index.html
и в нем подключим библиотеку и определим главный класс приложения, у нас он будет инкапсулировать в себе логику роутинга и управления всеми дочерними компонентами.
Веб-компоненты подарили нам возможность автовызова хука при появлении элемента в дереве, за которым закреплен наш класс, в дереве объектов браузера. В нем мы и инициализируем библиотеку роутинга кодом прямо из примера с гитхаба библиотеки (в реально жизни это стоит сделать красивее с модульной загрузкой).
<script src="/node_modules/navigo/lib/navigo.min.js"></script>
<my-app></my-app>
<script type="module">
class MyApp extends HTMLElement {
connectedCallback() {
let root = null;
let useHash = true; // Defaults to: false
let hash = '#!'; // Defaults to: '#'
this.router = new Navigo(root, useHash, hash);
}
}
customElements.define('my-app', MyApp);
</script>
Добавим обработку роутов:
connectedCallback() {
let root = null;
let useHash = true; // Defaults to: false
let hash = '#!'; // Defaults to: '#'
this.router = new Navigo(root, useHash, hash);
router
.on('page-a', () => {
this.innerHTML = '';
this.insertAdjacentHTML('beforeend', '<page-a></page-a>');
})
.on('page-b', () => {
this.innerHTML = '';
this.insertAdjacentHTML('beforeend', '<page-b></page-b>');
})
.on('*', () => {
this.innerHTML = '';
this.insertAdjacentHTML('beforeend', '<div>Please click links above</div>');
})
.resolve();
}
При каждом изменении роута наш компонент обновляет внутреннее содержимое добавляя в него новый тег. Осталось зарегистрировать эти теги за новыми компонентами страниц.
class PageA extends HTMLElement {
connectedCallback() {
this.insertAdjacentHTML('beforeend', '<div>This is a page A</div>');
}
}
class PageB extends HTMLElement {
connectedCallback() {
this.insertAdjacentHTML('beforeend', '<div>This is a page B</div>');
}
}
customElements.define('page-a', PageA);
customElements.define('page-b', PageB);
В самом верху страницы добавим ссылки, чтобы проверить навигацию:
<a href="page-a" data-navigo>Page A</a>
<a href="page-b" data-navigo>Page B</a>
атрибут data-navigo позволяет нажатия по ним обрабатывать роутером, а не осуществлять запросы на бекенд. Который пора уже запустить, например вот так:
npx http-server
открыть в браузере 127.0.0.1:8080 или какой он вам там напишет и убедиться, что все работает.
Теперь мы можем разнести все как полагается по отдельным файлам, приделать шаблонизацию и динамическую загрузку страниц, вынести роуты в концигурацию. Веб-компоненты возьмут на себя основную работу с Жизненным Циклом объектов приложения, только эвенты надо не забывать разбиндивать в хуке disconnectedCallback()
Поскольку я хотел показать насколько быстро это все делается, растягивать дальше статью пожалуй не буду;)
Об чем-то из этого я уже писал в статьях:
Быстрый старт с WebComponents
и
WebComponents как фреймворки, взаимодействие компонентов
Ждите новых открове^Wстатей, шэрьте и лайкайте!
Получившийся исходный код можно посмотреть вот репозитории на битбакете:
https://bitbucket.org/techminded/testnavigo/
justboris
А в чем смысл комбинации
this.innerHTML
иthis.insertAdjacentHTML
? Почему нельзя обойтись одним innerHTML:syncro Автор
innerHTML не во всех браузерах или вообще не вызывает рендер кастомных элементов, а в этом тут вся магия
justboris
А в каких это браузерах такое происходит? Насколько мне известно, во всех трех Firefox, Chrome, Safari, как и в полифиллах, работает как надо.
syncro Автор
что-то из микрософтовского семейства, теперь это не актуально уже конечно