В библиотеке Slim.js props используются для передачи данных от родительского компонента к дочернему. Это основной механизм, позволяющий компонентам взаимодействовать между собой и поддерживать реактивность. В Slim.js props обладают двунаправленной реактивной связью: изменение значения в родителе автоматически отражается в дочернем компоненте, если это предусмотрено настройкой.
Props объявляются в классе компонента с помощью статического свойства
observedAttributes. Каждое имя атрибута, указанное в
массиве, становится доступным через
this.<имя_атрибута> внутри компонента. Например:
import Slim from 'slim-js';
class UserCard extends Slim {
static get observedAttributes() {
return ['name', 'age'];
}
template() {
return Slim.html`
<div>
<h2>${this.name}</h2>
<p>Возраст: ${this.age}</p>
</div>
`;
}
}
Slim.tag('user-card', UserCard);
В этом примере компонент UserCard получает два пропса:
name и age. Любое изменение этих атрибутов в
родительском элементе автоматически вызовет обновление DOM внутри
компонента.
Передача данных происходит через HTML-атрибуты при использовании компонента:
<user-card name="Алексей" age="28"></user-card>
Если значение атрибута динамическое, можно использовать реактивные данные из родителя:
class App extends Slim {
static get observedAttributes() {
return ['user'];
}
constructor() {
super();
this.user = { name: 'Мария', age: 24 };
}
template() {
return Slim.html`
<user-card name="${this.user.name}" age="${this.user.age}"></user-card>
`;
}
}
Slim.tag('app-root', App);
В данном случае props name и age
автоматически получают значения из объекта user.
Props в Slim.js поддерживают строки, числа, булевы значения, объекты и массивы. Для корректного отображения сложных объектов необходимо использовать сериализацию при передаче через HTML-атрибут:
<user-card user='${JSON.stringify(this.user)}'></user-card>
В компоненте можно десериализовать объект:
get user() {
return JSON.parse(this.getAttribute('user'));
}
Для чисел и булевых значений также часто используют геттеры и сеттеры для автоматического преобразования типов:
get age() {
return Number(this.getAttribute('age'));
}
set age(value) {
this.setAttribute('age', value);
}
Slim.js автоматически отслеживает изменения атрибутов, указанных в
observedAttributes. Когда значение props изменяется,
вызывается метод attributeChangedCallback, который можно
переопределить для дополнительной логики:
attributeChangedCallback(name, oldValue, newValue) {
if (oldValue !== newValue) {
console.log(`Prop ${name} изменился с ${oldValue} на ${newValue}`);
}
}
Это позволяет создавать сложные сценарии реактивного обновления компонентов, не нарушая структуру DOM.
Props можно передавать через несколько уровней вложенности. Важно помнить, что каждый уровень должен явно объявлять получаемые атрибуты, иначе реактивность не будет работать:
class Profile extends Slim {
static get observedAttributes() {
return ['user'];
}
template() {
return Slim.html`
<user-card name="${this.user.name}" age="${this.user.age}"></user-card>
`;
}
}
Slim.tag('profile-view', Profile);
Здесь компонент Profile принимает объект
user и передаёт его дочернему компоненту
UserCard.
Для удобства можно задавать значения по умолчанию для props, чтобы компонент корректно работал, даже если родитель их не передал:
get name() {
return this.getAttribute('name') || 'Неизвестно';
}
get age() {
return Number(this.getAttribute('age') || 0);
}
Это предотвращает появление undefined в шаблоне и
упрощает обработку данных.
Когда props передаётся как объект или массив, Slim.js не отслеживает внутренние изменения структуры автоматически. Для реактивного обновления необходимо заново присвоить атрибут или использовать вспомогательные методы:
this.user = { ...this.user, age: 30 }; // вызовет обновление
Прямое изменение свойства объекта (this.user.age = 30)
не вызовет перерисовку, если атрибут не обновлён через сеттер.
Хотя props работают от родителя к дочернему компоненту, обратная связь реализуется через кастомные события:
this.dispatchEvent(new CustomEvent('update', {
detail: { age: 29 },
bubbles: true
}));
Родительский компонент может слушать эти события и обновлять свои данные, что обеспечивает двунаправленное взаимодействие.
Передача данных через props в Slim.js обеспечивает чёткую и
реактивную связь компонентов, сохраняя производительность и
упрощая архитектуру приложения. Правильное объявление
observedAttributes, использование геттеров/сеттеров и
сериализация объектов позволяют эффективно управлять любыми типами
данных и поддерживать масштабируемость.