Нажмите здесь, чтобы опубликовать эту статью в LinkedIn »

Что-то замечательное, что я стараюсь и делаю, чтобы оставаться на вершине своей игры, - это добавлять в свой колчан новые навыки и инструменты. По возможности я также стараюсь добавить немного магии сверху, чтобы убедиться, что все в порядке, и именно здесь в игру вступает Stencil.

«Волшебный многоразовый компилятор веб-компонентов» - Stenciljs.com

Наконец, ни один другой фреймворк javascript не выходит из команды, которая вкладывает деньги туда, где их рот, и выпускает свои собственные компоненты, созданные с помощью Stencil.

Этот инструмент, безусловно, дает некоторую магию, потому что, когда вы можете создавать настраиваемые компоненты, которые интегрируются где угодно, разработчик, наконец, может избавиться от беспокойства о том, какой интерфейсный фреймворк отталкивается во многих местах.

Чтобы применить эту магию на практике, мы собираемся создать боковое меню, которое является очень распространенным элементом в любом SPA. Если вы ищете готовый продукт, я связал репозиторий компонентов в github здесь.

Https://github.com/thielCole/stencil-side-menu

Начальный проект по созданию трафаретов

Отличный ресурс для начала создания компонента Stencil (особенно если вы хотите создать автономный компонент) - это Stencil Component Starter. Перейдите в каталог, в котором вы хотите разместить свой проект, и следуйте инструкциям.

// Installing the Stencil App Starter
git clone https://github.com/ionic-team/stencil-component-starter.git side-menu 
cd side-menu
git remote rm origin
npm install

Они дают вам отличную основу для начала, и ваша структура каталогов должна выглядеть примерно так.

Наша первая цель - переименовать все наши компоненты в боковое меню с MyComponent на SideMenu (боковое меню). Не считайте это простым шагом. Есть четыре файла, которые вам нужно изменить после того, как вы переименуете все свои файлы и папки из my-component в боковое меню.

// side-menu.tsx
@Component({
  tag: 'side-menu',
  styleUrl: 'side-menu.css',
  shadow: true
})
export class SideMenu {
...
// index.html
<!DOCTYPE html>
<html dir="ltr" lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-  scale=1.0, minimum-scale=1.0, maximum-scale=5.0">
  <title>Stencil Component Starter</title>
  <script src="/build/side-menu.js"></script>
</head>
<body>
  <side-menu></side-menu>
</body>
</html>
// stencil.config.js
exports.config = {
  namespace: 'side-menu',
  generateDistribution: true
};
exports.devServer = {
  root: 'www',
  watchGlob: '**/**'
}
// package.json
"name": "side-menu",
"version": "0.0.1",
"description": "Stencil Component Starter",
"main": "dist/side-menu.js",
"types": "dist/types/index.d.ts","collection": "dist/collection/collection-manifest.json",
"files": [
  "dist/"
],
"browser": "dist/side-menu.js",
...

Ваша окончательная файловая структура должна выглядеть примерно так.

Теперь, если мы запускаем npm start, мы действительно кое-что получим!

Определенно что-то, что нужно улучшить, было бы более простым способом создать новый компонент в нужном каталоге, но для бета-версии продукта (Stencil находится в стадии бета-тестирования) я могу видеть, что они делают до сих пор.

Сделать его настоящим боковое меню

Что ж, здесь немногое, но теперь вы все настроены, чтобы начать собственно создание своего компонента. Есть два основных свойства бокового меню: во-первых, оно перекрывается поверх текущего представления, а во-вторых, оно имеет серый фон (на мобильном устройстве). Давайте создадим это представление в методе render () нашего side-menu.tsx

return (
<div class="side-menu">
  <div class="menu-background">
  </div>
  <div class="actual-menu">
    This is my main menu!
  </div>
</div>
);

Теперь у нас есть боковое меню и фон. Чтобы все было красиво и красиво, добавьте эти стили в свой side-menu.css

.side-menu {
 position: absolute;
 top: 0px;
 left: 0px;
 height: 100%;
 width: 100%;
 z-index: 20;
 background-color: transparent !important;
 padding: 0;
}
.actual-menu {
 position: absolute;
 top: 0px;
 left: 0px;
 width: 250px;
 min-height: 100%;
 background-color: white;
 z-index: 30;
}
.menu-button {
 width: 100%;
 margin: 0px;
 padding: 10px;
}
.menu-background {
 position: absolute;
 background-color: rgba(38,38,38, 0.2);
 top: 0px;
 left: 0px;
 width: 100%;
 min-height: 100%;
 z-index: 5;
}

Это позволит нам иметь боковое меню, которое отображается автоматически и выглядит примерно так.

Добавление событий в компонент

Теперь, когда у нас есть настраиваемый компонент, который выглядит как боковое меню, нам также понадобится, чтобы он работал как боковое меню. Если вы видите в нашем текущем меню, выхода нет. Обычно на мобильном устройстве, если вы щелкнете по серой области фона, оно удалит меню и вернет вас к просматриваемому контенту, поэтому мы реализуем эту функцию.

Для этого нам понадобятся две функциональные возможности. Во-первых, нам нужно, чтобы наш компонент генерировал настраиваемое событие, которое я называю «backgroundToggle». Для этого мы импортируем Event и EventEmitter из @ stencil / core и прикрепим его к событию onclick для нашего div-фона меню.

// side-menu.tsx
@Event() backgroundToggle: EventEmitter;
menuToggle(e) {
  console.log('Background toggled menu', e);
  this.backgroundToggle.emit(e);
}
render() {
return (
      <div class="side-menu">
        <div class="menu-background" onClick={(e) => this.menuToggle(e)}>
      </div>
      <div class="actual-menu">
        This is my side menu!
      </div>
    </div>
  );
}

Это позволяет Stencil привязать наше событие menuToggle к собственному событию onClick из div menu-backgroud.

Прослушивание событий

Поскольку мы создаем автономный компонент, мы не хотим предполагать, что знаем, что пользователь хочет делать, когда кто-то нажимает на фон. Вместо этого мы должны реализовать способ прослушивания этого события на нашей основной странице index.html и использовать его, чтобы скрыть наше боковое меню. Это можно сделать двумя способами. Первый - реализовать тег Listen, который можно использовать, если у вас есть транспилятор, например машинописный текст.

// index.html with transpiler
@Listen('backgroundToggle')
function toggleBackground(e) {
  console.log('recieved event', e);
  document.getElementsByTagName('side-menu')[0].style.display = 'none';
}

К сожалению для нас, файл index.html, предоставленный Stencil, в любом случае не передается, поэтому нам нужно обязательно использовать функции es5, чтобы иметь возможность прослушивать наше сгенерированное событие. Это также будет считаться лучшей практикой, потому что мы хотим протестировать наш компонент таким образом, чтобы конечный пользователь мог его реализовать, и мы не можем рассчитывать на то, что они могут использовать TypeScript.

Чтобы реализовать работающий слушатель, мы используем нашу хорошо оформленную функцию document.addEventListener!

//index.html 
...
  <side-menu>
  </side-menu>
</body>
<script>
document.addEventListener('toggleBackground', function hideMenu(e) {
  console.log('Event Recieved');
  document.getElementsByTagName('side-menu')[0].style.display =   'none';
});

Теперь мы можем прослушивать наше сгенерированное событие на главной странице и соответствующим образом реагировать, когда кто-то нажимает на фон нашего меню!

Разрешение настройки пользователя с помощью ‹слота /›

Если мы действительно создаем компонент, который можно использовать в любом проекте, мы понятия не имеем, как кто-то захочет структурировать свои параметры меню. Это может быть часть авторизации пользователя, простой список пунктов меню или информационный диалог о том, на что кто-то смотрит.

<side-menu>
  <div class="example-button">This is a nav butt!</div>
</side-menu>

Чтобы включить этот вид настройки, нам нужно разрешить пользователю передавать HTML в боковое меню в качестве содержимого меню, и для этого у нас есть удобный тег ‹slot /›, который является невероятно мощным. Когда мы добавляем тег ‹slot /› к нашему компоненту, любой HTML-код, который разработчик добавляет внутри нашего настраиваемого тега, будет добавлен вместо ‹slot /›. Для нас мы хотим, чтобы это было добавлено в «фактическое меню» (именование не моя сильная сторона).

<div class="actual-menu">
  </slot>
</div>

Я не могу объяснить, насколько мощным может быть этот тег слота. В частности, для бокового меню вы захотите, чтобы пользователь мог добавлять кнопки навигации и настраиваемый контент, который без него был бы невозможен.

В сводке

Компилятор компонентов Stencil - это невероятно мощный инструмент, который позволяет создавать отличные кросс-фреймворки. Возможность стандартизировать компоненты и доставлять их в React, Vue, Angular или что угодно, что вам нравится, делает его очень полезным инструментом для всех (особенно ионных), кто хочет разрабатывать веб-компоненты и делиться ими между командами, проектами и предприятиями без беспокоясь о следующем горячем фреймворке. Я лично очень рад начать использовать и открывать исходный код некоторых пользовательских компонентов для улучшения сообщества.