SkateJS предоставляет мощный механизм для создания веб-компонентов с декларативным управлением свойствами и их синхронизацией с DOM-атрибутами. Ключевой особенностью является реактивная привязка свойств к атрибутам, которая позволяет автоматически обновлять отображение компонента при изменении данных и наоборот — отражать изменения атрибутов в свойствах.
В SkateJS свойства компонента определяются в объекте
props. Каждое свойство может иметь тип, значение по
умолчанию, а также флаг reflect, который отвечает за
автоматическое отражение значения свойства в атрибут
DOM-элемента.
Пример:
import { define, props, Component } from 'skatejs';
class MyElement extends Component {
static props = {
name: props.string({ reflect: true }),
age: props.number()
};
render() {
return <div>{this.name} — {this.age} лет</div>;
}
}
define('my-element', MyElement);
В этом примере свойство name имеет
reflect: true. Это означает, что любое изменение
this.name автоматически обновит соответствующий атрибут
name в DOM:
const el = document.querySelector('my-element');
el.name = 'Алексей';
console.log(el.getAttribute('name')); // "Алексей"
При этом свойство age не отражается в атрибуты, так как
флаг reflect отсутствует.
SkateJS поддерживает типизацию свойств через встроенные типы:
string, number, boolean,
array, object. Типы играют важную роль при
отражении значений в атрибуты:
true, отсутствие — false. Отражение
boolean-свойства в атрибут происходит автоматически.Пример с boolean:
class ToggleButton extends Component {
static props = {
active: props.boolean({ reflect: true })
};
toggle() {
this.active = !this.active;
}
}
define('toggle-button', ToggleButton);
При вызове toggle() значение active
изменится, а атрибут active будет добавлен или удален из
DOM, обеспечивая синхронизацию состояния компонента и его атрибутов.
SkateJS позволяет использовать функцию attribute для
точного контроля отображения свойства в атрибут. Это полезно, если нужно
кастомное преобразование, например, при работе с объектами или
массивами.
class CustomElement extends Component {
static props = {
data: props.string({
attribute: (value) => JSON.stringify(value),
reflect: true
})
};
}
define('custom-element', CustomElement);
const el = document.querySelector('custom-element');
el.data = { x: 10, y: 20 };
console.log(el.getAttribute('data')); // '{"x":10,"y":20}'
Отражение работает в обе стороны. Если атрибут изменяется напрямую в DOM, SkateJS автоматически обновляет соответствующее свойство:
el.setAttribute('name', 'Мария');
console.log(el.name); // "Мария"
Это обеспечивает двустороннюю реактивность: изменения через JavaScript и через DOM остаются синхронизированными.
Свойства с отражением можно создавать динамически через объект
props. Это особенно полезно при создании компонентов с
переменным набором атрибутов:
class DynamicProps extends Component {
static props = {
color: props.string({ reflect: true }),
size: props.number({ reflect: true })
};
}
define('dynamic-props', DynamicProps);
const el = document.querySelector('dynamic-props');
el.color = 'red';
el.size = 42;
console.log(el.getAttribute('color')); // "red"
console.log(el.getAttribute('size')); // "42"
reflectnull или undefined, атрибут
удаляется из DOM.reflect: true только для свойств, которые
должны быть доступны через DOM-атрибуты.Механизм отражения свойств в атрибуты в SkateJS обеспечивает
сильную связь между внутренним состоянием компонента и его
представлением в DOM. Это облегчает синхронизацию данных,
интеграцию с HTML и управляемость компонентов. Ключевые элементы —
reflect, типы свойств и возможность кастомного
преобразования через attribute.
Такой подход позволяет создавать динамические, реактивные веб-компоненты с минимальным количеством кода и высокой предсказуемостью поведения.