Концепция компонентов и их жизненный цикл

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

Компонент в Riot.js определяется с помощью специального синтаксиса тегов .riot или через функцию Riot.component(). Структура компонента включает следующие ключевые элементы:

  • Тег (template): HTML-разметка, определяющая визуальную часть компонента. Поддерживает привязку данных через синтаксис { }.
  • Скрипт (script): Логика компонента, управление состоянием, обработка событий, методы жизненного цикла.
  • Стили (style): Локальные стили, которые применяются только к данному компоненту, предотвращая конфликты с глобальными стилями.

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

<my-counter>
  <p>Счетчик: {count}</p>
  <button oncl ick={increment}>Увеличить</button>

  <script>
    export default {
      count: 0,
      increment() {
        this.count++
      }
    }
  </script>

  <style>
    p { color: blue; }
    button { font-weight: bold; }
  </style>
</my-counter>

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

Жизненный цикл компонента — это последовательность событий и этапов, через которые проходит компонент с момента создания до уничтожения. Riot.js предоставляет несколько ключевых методов для управления жизненным циклом:

onBeforeMount

Вызывается перед монтированием компонента в DOM. Позволяет подготовить данные или выполнить начальную инициализацию. На этом этапе элементы DOM ещё недоступны.

onBeforeMount() {
  this.count = 10
}

onMounted

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

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

onBeforeUpdate

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

onBeforeUpdate(newProps, newState) {
  console.log('Обновление с', this.count, 'на', newState.count)
}

onUpdated

Вызывается после того, как компонент обновился и DOM отражает новые данные. Полезно для синхронизации состояния с внешними библиотеками или DOM-манипуляциями.

onUpdated() {
  console.log('Компонент обновлен')
}

onBeforeUnmount

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

onBeforeUnmount() {
  console.log('Компонент скоро будет удален')
}

onUnmounted

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

onUnmounted() {
  console.log('Компонент удален')
}

Работа с состоянием и свойствами

Состояние компонента (state) управляется через объект this. Для реактивного обновления интерфейса необходимо изменять свойства состояния напрямую:

this.count++

Передача данных в компонент осуществляется через props, которые передаются как атрибуты тега:

<my-counter initial-count={5}></my-counter>

В компоненте их можно получить через this.props:

onBeforeMount() {
  this.count = this.props.initialCount || 0
}

События и привязка

Riot.js использует простую синтаксис-привязку событий через onclick, onchange и другие. Методы, определённые внутри компонента, автоматически имеют доступ к состоянию через this. Поддерживается двусторонняя привязка с помощью {}:

<input type="text" value={name} onin put={e => this.name = e.target.value}>
<p>Привет, {name}</p>

Вложенные компоненты и слоты

Riot.js позволяет создавать вложенные компоненты, что повышает повторное использование кода. Вложенные компоненты передают данные через props и могут содержать слоты (<slot></slot>), обеспечивающие гибкую вставку внешнего контента:

<panel>
  <slot></slot>
</panel>

<panel>
  <p>Внутренний контент панели</p>
</panel>

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

<panel>
  <slot name="header"></slot>
  <slot name="body"></slot>
</panel>

Резюме ключевых особенностей

  • Компоненты инкапсулируют HTML, CSS и JS, обеспечивая модульность.
  • Жизненный цикл предоставляет методы для управления состоянием и DOM на разных этапах.
  • Состояние (state) и свойства (props) управляют реактивностью интерфейса.
  • Поддерживаются вложенные компоненты и слоты для гибкой композиции интерфейса.
  • Привязка событий и данных упрощает синхронизацию интерфейса и логики.

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