Собственный Javascript в браузерах развился до такой степени, что использование библиотек может добавить ненужной сложности вашему приложению.
Как видно из данных caniuse.com, мы можем использовать модули уже в 69,19% браузеров, а Custom Elements v1 поддерживается в 78,28% браузеров.
С помощью полифиллов вы можете увеличить эти цифры еще больше.
Итак, сегодня мы напишем небольшое руководство о том, как написать блог, основанный на Custom Elements v1 и поддерживающий только новые модули, без необходимости связывания.
Я буду использовать некоторые самодельные минимальные библиотеки, чтобы упростить код, но вам это не обязательно.
Вы можете просмотреть полный код этого руководства.
https://github.com/tonis2/customElement-app
Итак, начнем.
Структура
Сначала давайте создадим файлы для нашего приложения.
Это простая основа для приложения JavaScript, у нас есть папка компонентов, назовите ее components или pages как хотите, но она содержит пользовательские элементы, которые затем вставляются позже. в приложение.
У нас также есть папка utils, я использую ее для файлов, которые экспортируют модули, которые вы хотели бы использовать внутри своих компонентов.
Они похожи на вспомогательные функции, которые внедряются в компоненты моим движком приложения.
В настоящее время мне нужно использовать его только для внедрения функций выборки JavaScript, поэтому я могу легко выполнять вызовы POST, GET.
Доступ к внедряемым утилитам возможен из конструктора всех компонентов, зарегистрированных в App-engine.
Например.
class Home extends HTMLElement { constructor(container) { super(); // These are injected into Element via App-engine. this.api = container.get("api"); this.router = container.get("router"); }
Контейнер — это контейнер карты JavaScript, и он содержит все, что экспортируется из utils index.js.
Маршрутизатор вводится движком автоматически.
Я также использую index.js в своих папках-контейнерах для экспорта всех компонентов.
Например.
//home.js class Home extends HTMLElement { ///component logic } export default Home;
и
///index.js export {default as home} from "./home.js";
Затем в файле запуска приложения мы можем просто импортировать все компоненты сразу в массив.
import * as components from "./components/index.js";
Запуск приложения
Каждому приложению, конечно же, нужен index.html, так что давайте начнем с него.
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>App</title> </head> <link rel="stylesheet" href="./styles/main.css"> <body> </body> <script src="https://cdnjs.cloudflare.com/ajax/libs/custom-elements/1.0.8/custom-elements.min.js"></script> <script type="module" src="./index.js" defer></script> </html>
Это то, что мы собираемся использовать, самое важное место для нас это
<script type="module" src="./index.js" defer></script>
Мы хотим, чтобы наши файлы JavaScript были модульными, иначе мы не можем использовать функции импорта и экспорта.
Далее мы запустим наше приложение в корне index.js.
Сверху импортируем сделанную мной библиотеку App-engine, вы можете сделать свою,
это 50 строк кода + роутер, я использовал роутер Navigo.
Основная работа, которую выполняет движок, заключается в загрузке ваших компонентов и утилит в память, привязке утилит и маршрутизатора к компонентам и предоставлении функции для отображения компонентов на веб-странице.
Итак импортируем все компоненты и утилиты + движок.
import App from "https://cdn.rawgit.com/tonis2/component-engine/58660d22/build/bundle.js"; import * as components from "./components/index.js"; import * as utils from "./utils/index.js";
Затем мы регистрируем наши компоненты/утилиты в движке.
Все зарегистрированные компоненты будут иметь имя файла + «-el»,
поэтому home.js станет "дом-эл"
App.register({ components, utils });
Затем мы должны запустить наш Application router, который уже включен в Engine.
В минимальном варианте использования это выглядит так.
App.router .on("/", params => { App.renderPage("home-el"); }) .on("/post/:id", params => { App.renderPage("post-el", post); }) .resolve(); App.router.notFound(() => { App.renderPage("home-el"); });
У нас есть маршруты, и когда маршрут приземляется, мы говорим Engine отобразить этот компонент и удалить старый компонент.
См. пример здесь.
Создание компонентов
Чтобы сделать пользовательские элементы, я рекомендую прочитать немного о Custom Elements V1 до этого. компиляция или библиотеки для их использования.
Поскольку у нас нет JSX, к которому привыкли разработчики React, я буду использовать библиотеку light-html, создание элементов Dom по-прежнему не очень удобно для нативного JavaScript.
Использование var element = document.createElement(tagName[, options]);
многое создает большой беспорядок, поэтому, на мой взгляд, самый простой способ создать HTML с помощью нативного JavaScript — это использовать шаблонные строки, а light-html сделает это за вас.
Или вы можете сделать это с помощью нативного js, как описано здесь.
Итак, давайте создадим простую домашнюю страницу с веб-компонентом v1.
Пример получает API и утилиту маршрутизатора в конструкторе, а в connectCallback отображает HTML.
В функции рендеринга я получаю случайные данные сообщений здесь, а затем визуализирую это.
Если вы нажмете на сообщение, оно перенаправит вас к этому сообщению.
Я также использую компонент уведомления просто как пример полезности API пользовательских элементов.
Это код для компонента уведомления
class Notifier extends HTMLElement { notify(info) { let notification = HTML`<span>${info}</span>`; notification.render(this); setTimeout(() => { notification.remove(); }, 2000); } }
Он показывает уведомление, а затем удаляет его.
Поэтому, когда я делаю вызов API, я использую.
let notifier = document.querySelector("notifier-el"); notifier.notify("Posts loading");
Вы можете использовать тот же метод для анимации загрузки или любой другой логики.
Я не стал рассматривать в этом посте каждый фрагмент кода, который у меня есть в приложении, но обязательно проверьте код github и попробуйте сами.