Использование веб-компонентов JavaScript
Веб-компоненты позволяют нам создавать многократно используемые пользовательские HTML-элементы, функциональность которых изолирована от остального кода. Это можно комбинировать с модулями ES для создания компонентной архитектуры для веб-сайтов с использованием HTML, CSS и ванильного JavaScript.
Следуя этому подходу, можно написать одностраничное приложение без использования каких-либо фреймворков или библиотек JavaScript. Эта статья поможет вам понять, как этого можно достичь.
Полный код доступен на GitHub.
Попробуйте эту архитектуру на StackBlitz.
Архитектура
Базовая папка приложения состоит из index.html
, script.js
и style.css
. Эти три файла в основном содержат шаблонный код, который может оставаться одинаковым для любого приложения, созданного с использованием этой архитектуры. Базовая папка также содержит папку 'src', в которой находится весь исходный код приложения. Эта папка содержит AppModule
, AppComponent
— базовый компонент, все дочерние компоненты и службы. AppModule
и AppComponent
являются обязательными файлами, которые образуют точку входа в настройку. Эти файлы также содержат некоторый шаблонный код.
Изучение базовой папки
Три файла в базовой папке (index.html
, script.js
, style.css
) образуют отправную точку для приложения.
Index.html
Это шаблонный HTML-файл, в котором в разделе <head>
определен файл script.js
и связан файл style.css
. Файл script.js
указывается с type='module'
для включения модулей ES. Он также помечен 'defer'
, чтобы загрузить его после загрузки HTML.
Тело index.html
не содержит ничего, кроме ссылки на <app-root>
. Этот файл является единственным файлом HTML во всем приложении.
script.js
Файл script.js
содержит определение AppModule
, которое формирует точку входа для остальной части приложения.
Файл style.css
содержит общие стили для приложения, а также связан с файлом index.html
.
Изучение папки src'
Основная часть приложения находится в папке src.
Модуль
Он начинается с appModule.js
, который является единственным файлом, на который есть ссылка вне папки «src». Он импортируется в файл script.js
, как показано выше. appModule.js
содержит экспортированный класс с именем 'AppModule'
, который содержит определение метода defineElements()
. Этот метод вызывается из файла script.js
. Все компоненты, присутствующие в приложении, включая базовый компонент и все дочерние компоненты, определяются в теле этого метода.
В приведенном ниже примере мы видим, что AppComponent
определяется как app-root
, а childOneComponent
определяется как child-one
.
Компоненты
Каждый компонент в этой архитектуре состоит из двух частей. Первый — это файл JavaScript, который определяет шаблон HTML и методы компонента. Второй файл CSS, который определяет стили для компонента и импортируется в шаблон.
Файл JavaScript компонента состоит из определения HTML template
и определения класса компонента. Класс компонента является расширением базового класса HTMLElement
. Этот класс определяет конструктор и два метода жизненного цикла компонента. Метод жизненного цикла connectedCallback()
запускается, как только компонент подключается (загружается) к DOM, а disconnectedCallback()
запускается, как только компонент отключается (удаляется) от DOM.
Базовый компонент
appComponent.js
— это веб-компонент JavaScript, который формирует базовый компонент приложения. Это можно рассматривать как обязательную часть архитектуры, поскольку это единственный компонент, доступный извне для файла index.html
как <app-root>
.
В приведенном выше примере шаблон appComponent
содержит тег <style>
, который импортирует appComponent.css
, и тег <div>
, формирующий тело компонента. В теле компонента есть тег <h1>
с заголовком 'App Component'
и тег <child-one>
.
Класс AppComponent
содержит базовый шаблонный код веб-компонента, необходимый для нормальной работы приложения.
Дочерние компоненты
Дочерние компоненты помещаются в папку components. Все создаваемые дочерние компоненты должны быть определены в AppModule
и напрямую или косвенно связаны с appComponent
.
В приведенном выше примере шаблон childOneComponent
содержит тег <style>
, который импортирует childOneComponent.css
, и тег <div>
, формирующий тело компонента. В теле есть тег <h2>
с заголовком 'Child One'
.
Это приложение при запуске формирует указанную выше структуру DOM. <app-root>
содержит тело AppComponent
в Shadow Root. Точно так же тело компонента <child-one>
содержится во вложенном теневом корне.
Услуги
Службы — это классы, содержащие набор статических функций, которые помогают приложению взаимодействовать с внешними службами, API или базами данных. Они используются для изоляции кода, ссылающегося на внешние ресурсы, от компонента. Службы размещаются в папке services, вложенной в папку src.
Доступ к сервисам возможен из любой точки приложения. Его необходимо импортировать в соответствующий файл, где он будет использоваться.
Приведенный выше пример SampleDataService
содержит статический массив state
и два других статических метода для управления state
. Метод addItem()
помещает элемент в state
, а метод getItem()
получает элемент из state
с помощью id
. Эти методы могут быть вызваны из любой точки приложения.
import { SampleDataService } from "./services/SampleDataService.js";
SampleDataService
импортируется в соответствующий файл, где он будет использоваться. Если мы хотим добавить элемент или два в состояние после загрузки AppComponent
, мы вызываем SampleDataService.addItem()
из connectedCallback
из AppComponent
.
connectedCallback() { SampleDataService.addItem({ id: 1, value: “Item 1” }); SampleDataService.addItem({ id: 2, value: “Item 2” }); }
Если мы хотим вывести определенный элемент на консоль после загрузки ChildOneComponent
, мы вызываем SampleDataService.getItem(id)
, передавая ему идентификатор элемента из connectedCallback
из ChildOneComponent
. Затем мы можем вывести значение на консоль, используя console.log()
.
connectedCallback() { let item = SampleDataService.getItem(1); console.log("Child One: ", item); }
Описанный выше подход к управлению состоянием небезопасен из-за изменяемой переменной состояния. Состояние может быть изолировано от служб с помощью шаблона Redux для повышения безопасности.
Заключение
В завершение мы рассмотрели, как создать одностраничное приложение с использованием веб-компонентов и модулей JavaScript ES. Мы изучили архитектуру и структуру папок, созданные для этого подхода. Мы также изучили все файлы, которые требуются в качестве шаблона для приложения, и увидели, как его можно настроить.
Код для этой архитектуры доступен на GitHub.
Вы можете опробовать эту архитектуру на StackBlitz.
Дополнительные материалы на PlainEnglish.io. Подпишитесь на нашу бесплатную еженедельную рассылку новостей. Подпишитесь на нас в Twitter и LinkedIn. Присоединяйтесь к нашему сообществу Discord.