Компонентная архитектура

Marko — это современный фреймворк для разработки интерфейсов на JavaScript, ориентированный на высокую производительность и удобство работы с компонентами. Компонентная архитектура в Marko позволяет создавать повторно используемые, изолированные блоки интерфейса с чётко определённой логикой и состоянием.

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

Компонент в Marko состоит из трёх основных частей:

  1. Шаблон (Template).marko файл, в котором описывается разметка компонента с использованием синтаксиса Marko. Шаблон поддерживает динамическое связывание данных и рендеринг вложенных компонентов.
  2. Логика (Logic) — JavaScript-модуль, связанный с шаблоном. Здесь описывается реактивное состояние, обработчики событий и методы жизненного цикла компонента.
  3. Стили (CSS/SCSS) — локальные стили компонента, которые могут быть встроены через <style> внутри .marko файла или подключены отдельным файлом.

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

<template>
  <div class="counter">
    <h1>${state.count}</h1>
    <button on-click('increment')>Увеличить</button>
  </div>
</template>

<script>
  class {
    state = { count: 0 };

    increment() {
      this.state.count += 1;
    }
  }
</script>

<style>
  .counter {
    text-align: center;
    font-family: Arial, sans-serif;
  }
  button {
    padding: 0.5em 1em;
    margin-top: 10px;
  }
</style>

Управление состоянием компонента

Marko использует реактивное состояние через объект state. Любое изменение свойства state автоматически вызывает обновление интерфейса. Это позволяет легко создавать интерактивные компоненты без необходимости вручную управлять DOM.

Ключевые особенности:

  • Локальное состояние — каждый компонент имеет собственный объект state.
  • Реактивность — обновление состояния вызывает повторный рендер только изменённых частей шаблона.
  • Простота передачи данных — родительский компонент может передавать значения через атрибуты, которые становятся доступными в дочернем компоненте.
<MyComponent count=5 />

В дочернем компоненте:

<h1>${input.count}</h1>

Жизненный цикл компонента

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

  • onCreate() — вызывается при создании компонента, до монтирования в DOM.
  • onMount() — вызывается после монтирования компонента в DOM.
  • onUpdate() — вызывается после обновления состояния компонента.
  • onDestroy() — вызывается перед удалением компонента из DOM.

Пример использования методов жизненного цикла:

class {
  onCreate() {
    this.state.count = 0;
  }

  onMount() {
    console.log('Компонент смонтирован');
  }

  onUpdate() {
    console.log('Состояние обновлено', this.state.count);
  }

  onDestroy() {
    console.log('Компонент удаляется');
  }
}

Вложенные компоненты и композиция

Компоненты Marko могут быть вложены друг в друга, что позволяет строить сложные интерфейсы из простых повторно используемых блоков. Для этого используется синтаксис <ИмяКомпонента />.

Пример:

<template>
  <Card title="Заголовок">
    <p>Содержимое карточки</p>
  </Card>
</template>

Внутри Card.marko можно использовать слот для передачи контента:

<div class="card">
  <h2>${input.title}</h2>
  <div class="content">
    <slot />
  </div>
</div>

Передача событий от дочерних компонентов

Для связи дочернего компонента с родительским используется механизм событий. Дочерний компонент может вызвать событие, которое родитель слушает через атрибут on-*.

Пример:

<!-- Родительский компонент -->
<ChildComponent on-increment('handleIncrement') />

<script>
  class {
    handleIncrement(event) {
      console.log('Дочерний компонент увеличил счетчик', event.detail);
    }
  }
</script>

В дочернем компоненте:

this.emit('increment', { value: this.state.count });

Оптимизация рендера

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

Итоговая структура крупного проекта

В проекте на Marko компоненты обычно организуются по следующему принципу:

src/
  components/
    Header/
      index.marko
      style.css
    Footer/
      index.marko
      style.css
    Button/
      index.marko
      style.css
  pages/
    Home.marko
    About.marko

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

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