Валидация свойств и типов

Lit является легковесным фреймворком для создания веб-компонентов, который строится на стандартах Web Components и предоставляет декларативный способ работы с DOM. Одной из ключевых возможностей Lit является система управления свойствами (properties) компонентов, включая их типизацию и валидацию.


Объявление свойств

Свойства в Lit объявляются с помощью статического поля properties внутри класса компонента, наследующегося от LitElement. Каждое свойство может иметь определённый тип и дополнительные параметры:

import { LitElement, html } from 'lit';

class MyElement extends LitElement {
  static properties = {
    name: { type: String },
    age: { type: Number },
    active: { type: Boolean },
    settings: { type: Object },
    tags: { type: Array }
  };

  constructor() {
    super();
    this.name = '';
    this.age = 0;
    this.active = false;
    this.settings = {};
    this.tags = [];
  }

  render() {
    return html`
      <p>${this.name} (${this.age})</p>
      <p>Status: ${this.active ? 'Active' : 'Inactive'}</p>
      <p>Tags: ${this.tags.join(', ')}</p>
    `;
  }
}

customElements.define('my-element', MyElement);

Ключевые моменты:

  • type указывает тип данных, который Lit будет использовать при преобразовании атрибутов HTML в свойства компонента.
  • Свойства могут иметь значения по умолчанию, устанавливаемые в конструкторе.
  • Типы поддерживаются стандартные: String, Number, Boolean, Array, Object.

Преобразование атрибутов в свойства

Lit автоматически синхронизирует HTML-атрибуты и свойства компонентов. Например:

<my-element name="Alice" age="30" active></my-element>
  • Атрибут name преобразуется в строку.
  • Атрибут age преобразуется в число.
  • Атрибут active конвертируется в булев тип. Атрибут присутствует → true, отсутствует → false.

Это преобразование выполняется автоматически, что позволяет минимизировать ручную валидацию на этапе инициализации.


Кастомная валидация

Lit предоставляет возможность проверки и преобразования значений вручную через converter. Это полезно, когда требуется более сложная логика, например, проверка диапазонов чисел или форматов строк.

static properties = {
  age: {
    type: Number,
    converter: {
      fromAttribute: (value) => {
        const num = Number(value);
        if (isNaN(num) || num < 0) throw new Error('Возраст должен быть положительным числом');
        return num;
      },
      toAttribute: (value) => value.toString()
    }
  }
};
  • fromAttribute — преобразует значение атрибута в свойство. Можно добавить любую валидацию.
  • toAttribute — преобразует свойство в атрибут при необходимости синхронизации.

Реактивные свойства и наблюдение изменений

Lit позволяет отслеживать изменения свойств и реагировать на них через метод updated:

updated(changedProperties) {
  if (changedProperties.has('age')) {
    console.log(`Возраст изменён на ${this.age}`);
  }
}
  • changedProperties содержит карту старых значений.
  • Это позволяет выполнять дополнительные проверки и корректировки после валидации и привязки значений.

Комплексные типы и вложенные объекты

Для массивов и объектов важна глубокая валидация, так как Lit не отслеживает изменения внутренних свойств объекта автоматически. Для этого рекомендуется создавать копию объекта или массива при изменении:

this.settings = { ...this.settings, theme: 'dark' };
this.tags = [...this.tags, 'new'];
  • Прямое изменение элементов массива (this.tags.push('new')) не вызовет перерисовку.
  • Использование spread-операторов гарантирует, что Lit зафиксирует изменение.

Ограничения типов

  • Boolean: присутствие атрибута → true, отсутствие → false. Атрибуты, заданные как false, фактически удаляются из DOM.
  • Number: если значение не может быть преобразовано в число, Lit вернёт NaN. Валидацию необходимо выполнять вручную.
  • Array и Object: Lit не сериализует сложные структуры в атрибуты автоматически. Нужно использовать конвертеры или JSON-строки.

Практические рекомендации

  1. Всегда задавать значения по умолчанию в конструкторе, чтобы избежать undefined.
  2. Использовать конвертеры для сложных правил валидации.
  3. Копировать объекты и массивы при изменении, чтобы триггерить реактивность.
  4. Обрабатывать ошибки в fromAttribute, чтобы компонент не ломался при некорректных данных.
  5. Использовать updated для отслеживания изменений и выполнения дополнительной логики после валидации.

Система валидации и типизации Lit обеспечивает стабильное и предсказуемое поведение компонентов, сокращает количество багов при работе с HTML-атрибутами и позволяет строить сложные, реактивные интерфейсы с минимальной ручной обработкой данных.