Внутренним состоянием в Slim.js считается набор данных, влияющих на отображение компонента и недоступных напрямую извне. Состояние служит источником истинных значений для шаблона, методов и вычислимых свойств. Любое изменение поля состояния приводит к обновлению UI без ручного вмешательства в DOM.
Slim-компонент определяет состояние на уровне экземпляра класса. Для этого используются обычные поля или геттеры/сеттеры, а также вспомогательные методы для реактивного обновления представления.
Базовая инициализация выполняется в конструкторе или при объявлении полей класса:
class Counter extends Slim {
count = 0;
}
Переменные, определённые таким образом, автоматически становятся частью реактивного состояния. В шаблоне к ним обращаются через двойные фигурные скобки:
<span>{{count}}</span>
Ключевой момент: состояние должно изменяться через присвоение. Slim.js отслеживает сеттер и инициирует обновление представления:
increment() {
this.count++;
}
При вызове метода increment шаблон обновляется без
дополнительных вызовов рендеринга.
Сложные зависимости внутри компонента удобно инкапсулировать в вычислимые геттеры:
get doubled() {
return this.count * 2;
}
В шаблоне вычислимое свойство ведёт себя как обычное состояние:
<span>{{doubled}}</span>
Вычисление выполняется при каждом обновлении зависимости, не требуя ручного кэширования.
Slim.js позволяет связывать события интерфейса с методами компонента:
<button click="increment">+</button>
Методы получают доступ к состоянию через this, что
обеспечивает тесную связь логики и данных. События, обработанные таким
образом, поддерживают реактивный жизненный цикл обновления.
Сложные компоненты нередко используют специальные методы для
отслеживания изменений. Slim.js предоставляет хук
onBeforeUpdate и onAfterUpdate. Они позволяют
выполнять дополнительные действия при изменениях состояния:
onAfterUpdate(prop, value) {
if (prop === 'count' && value > 10) {
console.log('Порог достигнут');
}
}
Система передаёт имя изменившегося поля и новое значение, что упрощает построение внутренних реакций и валидации.
Slim.js различает два уровня данных: внутреннее состояние и публичные свойства. Публичные свойства доступны через атрибуты:
<counter initial="5"></counter>
Компонент принимает значение атрибута и может использовать его для инициализации состояния:
onCreated() {
this.count = Number(this.initial);
}
Публичные свойства работают как интерфейс обмена данными между компонентами, а состояние остаётся локальным.
Slim-компонент проходит ряд стадий: создание, монтирование,
обновление, удаление. Внутреннее состояние присутствует на всех этапах.
Инициализация может происходить в onCreated, а интеграция с
DOM — в onAdded:
onAdded() {
this.count = 1;
}
Изменение состояния в ранних хуках приводит к первичному рендерингу без лишних перерисовок.
В Slim.js обновления состояния пакетируются. При множественных изменениях переменных в рамках одного синхронного блока обновление шаблона выполняется один раз. Это снижает нагрузку на DOM и повышает производительность:
batchUpdate() {
this.count++;
this.count++;
this.count++;
}
Вёрстка обновится единоразово после завершения метода.
Slim.js поддерживает условные и повторяющиеся конструкции с использованием состояния. Например:
<div s:if="count > 0">
Положительное значение
</div>
Для списков:
<li s:repeat="item in items">
{{item}}
</li>
Эти директивы синхронизируются с изменениями состояния и корректно обновляют DOM по мере их появления, удаления или изменения.
Внутреннее состояние не должно зависеть от внешнего окружения. Такая изоляция облегчает тестирование и повторное использование компонентов. Slim.js поощряет приватные поля:
#internalValue = 0;
Приватность предотвращает непредсказуемые изменения извне и обеспечивает стабильность работы.
Передача данных между компонентами осуществляется через свойства и события. Внутреннее состояние никогда не передаётся напрямую. Потомок может генерировать событие, а родитель обновлять своё состояние в ответ:
this.dispatchEvent(new CustomEvent('update', { detail: value }));
Такой паттерн обеспечивает однонаправленный поток данных и снижает связанность.
Состояние может включать сложные структуры: объекты, массивы, карты. Slim.js отслеживает только ссылку. Изменения внутри структуры требуют обновления ссылки, иначе шаблон не узнает об изменении:
this.items = [...this.items, newItem];
Пересоздание структуры сохраняет реактивность даже при глубоко вложенных данных.
При большом объёме состояния возникает необходимость выбора минимального набора данных для обновления шаблона. Slim.js позволяет оптимизировать шаблон с помощью отдельных подкомпонентов и избирательных вычислений. Разделение крупного состояния на логические участки предотвращает избыточную перерисовку.
Асинхронный запрос к серверу обычно инициируется после монтирования компонента:
async onAdded() {
const response = await fetch('/api/data');
this.items = await response.json();
}
Полученные данные становятся частью состояния и автоматически приводят к перерисовке компонента.
Ошибки при изменении состояния отслеживаются отдельно от отображения. Slim.js предоставляет механизмы обработки ошибок уровня компонента, что позволяет хранить ошибки в специальном поле:
try {
this.count = parseInt(value);
} catch(e) {
this.error = e.message;
}
Шаблон может отображать текущее состояние ошибки без вмешательства в логику вычислений.
Эволюция состояния внутри компонента происходит по мере усложнения сценариев использования. На ранних этапах используются простые примитивы, затем вводятся вычислимые геттеры, события, хранилища и серверные данные. Slim.js сохраняет единый принцип: любое изменение состояния ведёт к обновлению представления и синхронизации логики с UI.