Передача данных через props

В библиотеке Slim.js props используются для передачи данных от родительского компонента к дочернему. Это основной механизм, позволяющий компонентам взаимодействовать между собой и поддерживать реактивность. В Slim.js props обладают двунаправленной реактивной связью: изменение значения в родителе автоматически отражается в дочернем компоненте, если это предусмотрено настройкой.

Определение 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

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);
}

Обновление props и реактивность

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

Для удобства можно задавать значения по умолчанию для 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, использование геттеров/сеттеров и сериализация объектов позволяют эффективно управлять любыми типами данных и поддерживать масштабируемость.