Свойства компонента и их отслеживание

Свойства компонента в Slim.js представляют собой минималистичный способ хранения состояния и связи между данными и шаблоном. Любое свойство, определённое на экземпляре компонента, автоматически отражается в DOM, если оно используется в привязках или логических выражениях. Такой подход делает компонент предсказуемым и упрощает управление состоянием.

Свойства компонента задаются как обычные поля класса. При создании экземпляра Slim.js преобразует их в реактивные величины. Использование сеттеров и геттеров избыточно: фреймворк самостоятельно перехватывает изменения.

Пример структуры класса:

class CounterComponent extends Slim {
  count = 0
}
customElements.define('x-counter', CounterComponent)

Поле count автоматически становится реактивным. В шаблоне его можно привязать:

<span>{{count}}</span>

При изменении count содержимое span будет обновлено без дополнительных вызовов.

Инициализация свойств

Инициализация свойств допускается в конструкторе или на уровне объявления поля. Разница заключается лишь в моменте создания. Slim.js не требует специальных методов для регистрации свойств или явного описания реактивности.

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

Отслеживание изменений

Slim.js внедряет наблюдение за изменениями через перехват присвоений. При обновлении значения производится повторный рендер участка шаблона, где свойство используется. Механизм обновлений работает дифференцированно: перерисовывается только фрагмент, связанный с конкретной привязкой.

Ключевые особенности отслеживания

  • Реактивность основана на перехвате свойств экземпляра.
  • Обновление изолировано и не запускает полный рендер компонента.
  • Логические блоки s:if, s:repeat и вычисляемые выражения реагируют на изменение значений.
  • Отслеживаются только простые присвоения. Мутации вложенных структур требуют переустановки свойства.

Например, при работе с массивом:

this.items.push(newItem)   // шаблон не обновится
this.items = [...this.items, newItem]   // сработает реактивность

Это связано с тем, что Slim.js сравнивает именно значение поля, а не внутреннее состояние объекта.

Привязка свойств в шаблоне

Slim.js допускает две основные формы привязки: интерполяции и директивы.

Интерполяция значений

Используется для простых текстовых выражений:

{{title}}

При обновлении title фреймворк изменяет текстовую ноду.

Директивы и атрибутные привязки

Slim.js превращает выражения вроде:

<input value="{{name}}">

в реактивное связывание. Аналогично обрабатываются логические директивы:

<div s:if="visible">

и списковые конструкции:

<li s:repeat="item in items">

В каждом случае изменения свойства инициируют локальное обновление шаблона.

Вычисляемые выражения

Внутри привязки разрешено использование простых выражений:

{{count * 2}}
{{items.length}}

Вычисление производится при каждом изменении участвующих свойств. Slim.js не создаёт кеш выражений и не отслеживает зависимостей явно, что упрощает модель поведения.

Односторонняя и двусторонняя реактивность

Slim.js обеспечивает одностороннее обновление DOM при изменении состояния компонента. Для двустороннего связывания применяются слушатели событий. Типичный шаблон:

<input value="{{name}}" on:input="name = this.value">

Обновление name приводит к обновлению DOM, а событие input корректирует значение свойства.

Свойства и жизненный цикл

Slim.js предоставляет хуки onBeforeUpdate и onUpdated, реагирующие на обновления шаблона. Эти методы вызываются после изменения свойств и завершения рендера. Такая последовательность обеспечивает согласованность состояния.

Ключевой момент: реактивность активна до вызова onMount, что позволяет использовать начальные значения в шаблоне сразу после создания компонента.

Наблюдение сложных структур

Slim.js не применяет глубокого наблюдения. Массивы и объекты не отслеживаются поэлементно. Для корректного обновления вложенных данных требуется присваивание нового значения:

this.config = {...this.config, theme: 'dark'}

Это правило распространяется на любые вложенные структуры и исключает скрытые мутации.

Оптимизация реактивности

Принцип оптимизации в Slim.js основан на минимальном количестве обновлений и точном определении затронутых узлов. Такой подход делает реактивность предсказуемой и не вмешивается в логику приложения.

Практические последствия

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

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