Создание и регистрация компонентов

Marko — это современный фреймворк для создания веб-приложений, ориентированный на производительность и простоту использования. Он использует компонентный подход, позволяя разработчикам создавать интерфейсы как независимые и переиспользуемые блоки. В этой части рассмотрим процесс создания и регистрации компонентов в Marko.

Структура компонента

Каждый компонент в Marko состоит из нескольких частей: шаблона (markup), JavaScript-логики и стилей. Шаблон определяет структуру HTML, JavaScript обрабатывает логику компонента, а стили — его внешний вид. Для простоты, шаблон и логику часто объединяют в один файл с расширением .marko.

Пример базового компонента:

<!-- my-component.marko -->
<div class="my-component">
  <h1>Hello, ${data.name}!</h1>
  <button on-click("handleClick")>Click me</button>
</div>

<script>
  module.exports = class {
    handleClick() {
      console.log("Button clicked!");
    }
  };
</script>

<style>
  .my-component {
    background-color: lightblue;
    padding: 20px;
    border-radius: 5px;
  }

  h1 {
    color: darkblue;
  }
</style>

В данном примере:

  • HTML-разметка в шаблоне компонента отображает данные и привязывает обработчик события к кнопке.
  • Логика компонента реализована с помощью класса, где определен метод для обработки кликов по кнопке.
  • Стили компонента заключены внутри тега <style>.

Использование данных в компонентах

Компоненты Marko могут принимать данные в виде пропсов (или data). Эти данные могут быть переданы компоненту при его рендеринге. В шаблоне компонента можно обращаться к этим данным с помощью синтаксиса ${data.someValue}.

Пример использования данных:

<!-- user-profile.marko -->
<div class="user-profile">
  <h2>${data.userName}</h2>
  <p>${data.userBio}</p>
</div>

При рендеринге компонента данные передаются в объект data, и шаблон автоматически отображает их.

const template = require("./user-profile.marko");

template.render({ userName: "Иван Иванов", userBio: "Программист с опытом работы 5 лет" });

Регистрация компонента

Для того чтобы компонент мог быть использован в других частях приложения, его необходимо зарегистрировать. В Marko компоненты регистрируются с использованием системы модулей, поддерживающей CommonJS или ES6 импорты.

  1. Импорт компонента:

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

    const Component = require('./my-component.marko');
  2. Использование компонента в шаблоне:

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

    <my-component name="Alex" />

    Важно отметить, что Marko автоматически определяет компоненты по имени. Таким образом, my-component будет автоматически связываться с файлом my-component.marko, если компонент зарегистрирован в том же проекте.

Работа с асинхронными данными

Компоненты Marko могут работать с асинхронными данными, что особенно полезно при работе с сервером или сторонними API. Для этого можно использовать async-методы или промисы в методах компонента.

module.exports = class {
  async onCreate() {
    this.user = await fetchUserDataFromAPI();
  }
}

В этом примере метод onCreate является асинхронным и выполняет запрос к API для получения данных пользователя.

Локальные компоненты и вложенные компоненты

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

Пример вложенного компонента:

<!-- parent-component.marko -->
<div class="parent">
  <child-component name="child 1" />
  <child-component name="child 2" />
</div>

При этом child-component может быть любым компонентом Marko, зарегистрированным и доступным для использования внутри родителя.

Повторное использование и динамическое добавление компонентов

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

<!-- list-component.marko -->
<ul>
  <for|item of data.items|>
    <li>${item.name}</li>
  </for>
</ul>

В данном примере используется цикл for, который позволяет динамически рендерить элементы из массива data.items.

Рендеринг компонентов на сервере

Marko был спроектирован с учетом рендеринга на сервере. Серверный рендеринг (SSR) помогает ускорить загрузку страницы и улучшить SEO. Компоненты, написанные в Marko, могут быть рендерены сервером и отправлены на клиент в виде готового HTML.

const marko = require('marko');
const template = require('./my-component.marko');

template.render({ name: 'Alex' }, res);

Этот код рендерит компонент и отправляет готовую разметку в ответ на HTTP-запрос.

Регистрация компонентов в приложении

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

Пример регистрации в Express:

const express = require('express');
const app = express();

const markoExpress = require('@marko/express');
app.use(markoExpress());

app.get('/', (req, res) => {
  const template = require('./views/home.marko');
  template.render({ title: 'Home Page' }, res);
});

В данном примере компонент рендерится при каждом запросе, и данные передаются через объект data.

Заключение

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