Классы и интерфейсы

FAST Element — это современная библиотека для создания веб-компонентов на основе стандартов Web Components с использованием реактивного программирования. Основными строительными блоками в FAST являются классы компонентов и их интерфейсы, обеспечивающие строгую типизацию, модульность и повторное использование кода.


Определение классов компонентов

Класс компонента в FAST Element создаётся через наследование от базового класса FASTElement. Базовый класс предоставляет все необходимые методы жизненного цикла, реактивные свойства и шаблонное связывание данных.

import { FASTElement, html, css, customElement, attr } from "@microsoft/fast-element";

@customElement({
    name: "my-element",
    template: html`<p>${x => x.message}</p>`,
    styles: css`p { color: blue; }`
})
class MyElement extends FASTElement {
    @attr message = "Привет, FAST!";
}

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

  • @customElement — декоратор для регистрации компонента как кастомного элемента.
  • template — HTML-шаблон с поддержкой реактивных выражений.
  • styles — CSS-стили компонента.
  • @attr — декоратор для реактивного свойства, которое синхронизируется с атрибутами DOM.

Реактивные свойства и их типизация

FAST Element поддерживает декларацию свойств с помощью декораторов @attr и @observable. Разница в том, что @attr связывает свойство с DOM-атрибутом, а @observable — это внутреннее реактивное состояние компонента без привязки к атрибутам.

import { observable } from "@microsoft/fast-element";

class CounterElement extends FASTElement {
    @observable count = 0;

    increment() {
        this.count++;
    }
}

Особенности:

  • Изменение @observable свойства автоматически инициирует обновление шаблона.
  • Тип свойства можно явно указать для TypeScript:
@observable count: number = 0;

Интерфейсы для компонентов

Интерфейсы позволяют определить структуру данных, ожидаемую компонентом, и упростить работу с типами в TypeScript. В FAST Element интерфейсы используются для типизации свойств компонентов и событий.

interface User {
    name: string;
    age: number;
}

class UserCard extends FASTElement {
    @attr user!: User;
}

Преимущества:

  • Строгая типизация свойств упрощает работу с IDE и предотвращает ошибки на этапе компиляции.
  • Облегчает интеграцию с внешними API и библиотеками.

Жизненный цикл компонента

Классы FAST Element имеют набор методов жизненного цикла, которые можно переопределять:

  1. connectedCallback() — вызывается при добавлении компонента в DOM.
  2. disconnectedCallback() — вызывается при удалении компонента из DOM.
  3. attributeChangedCallback(name, oldValue, newValue) — реагирует на изменения атрибутов.
  4. propertyChangedCallback(name, oldValue, newValue) — срабатывает при изменении реактивных свойств.
class TimerElement extends FASTElement {
    @observable seconds = 0;

    connectedCallback() {
        super.connectedCallback();
        this.interval = setInterval(() => this.seconds++, 1000);
    }

    disconnectedCallback() {
        clearInterval(this.interval);
        super.disconnectedCallback();
    }
}

Наследование и расширение компонентов

FAST Element поддерживает наследование, что позволяет создавать базовые компоненты и расширять их функциональность:

class BaseButton extends FASTElement {
    @attr disabled = false;
    click() {
        if (!this.disabled) console.log("Clicked");
    }
}

@customElement({ name: "primary-button", template: html`<button>${x => x.label}</button>` })
class PrimaryButton extends BaseButton {
    @attr label = "Нажми меня";
}

Особенности наследования:

  • Можно расширять как функциональность, так и шаблон компонента.
  • Декораторы и реактивные свойства наследуются автоматически.

Типизация событий и интерфейсы

Для сложных компонентов важно описывать события через интерфейсы. Это позволяет строго определить структуру передаваемых данных:

interface ToggleEventDetail {
    checked: boolean;
}

class ToggleSwitch extends FASTElement {
    @observable checked = false;

    toggle() {
        this.checked = !this.checked;
        this.$emit<ToggleEventDetail>("change", { checked: this.checked });
    }
}

Метод $emit отправляет событие с типизированными данными, что особенно полезно в TypeScript-проектах.


Миксины и повторное использование кода

FAST Element поддерживает создание миксинов — функций, возвращающих классы с дополнительными методами и свойствами:

function Loggable<T extends new (...args: any[]) => FASTElement>(Base: T) {
    return class extends Base {
        log(message: string) {
            console.log(`[${this.constructor.name}]: ${message}`);
        }
    };
}

class MyWidget extends Loggable(FASTElement) {
    doSomething() {
        this.log("Действие выполнено");
    }
}

Преимущество миксинов — модульность и повторное использование функциональности без дублирования кода.


Итоговая структура класса FAST Element

  1. Декоратор @customElement — регистрация компонента.
  2. Шаблон и стилиtemplate и styles.
  3. Реактивные свойства@attr и @observable.
  4. Методы жизненного циклаconnectedCallback, disconnectedCallback, propertyChangedCallback.
  5. События и интерфейсы — строгая типизация через TypeScript.
  6. Наследование и миксины — расширяемость и повторное использование.

Эта структура обеспечивает создание гибких, типизированных и легко поддерживаемых веб-компонентов, полностью интегрированных с современным стеком JavaScript.