Миграция с Web Components v0

Основы различий между Web Components v0 и FAST Element

Web Components v0 представляли собой ранние спецификации Custom Elements, Shadow DOM и HTML Imports. Основные ограничения v0 заключались в ограниченной поддержке стандартов, отсутствием удобного механизма реактивного связывания данных и сложностями в управлении состоянием компонентов.

FAST Element решает эти проблемы, предоставляя современный реактивный фреймворк для создания веб-компонентов, полностью совместимый с последними стандартами Custom Elements и Shadow DOM. Он добавляет декларативное связывание данных, шаблонизацию через HTML-шаблоны с реактивными выражениями и удобные жизненные циклы компонентов.

Создание компонентов

В Web Components v0 компонент обычно создавался через document.registerElement, что выглядело так:

var MyElement = document.registerElement('my-element', {
  prototype: Object.create(HTMLElement.prototype, {
    createdCallback: {
      value: function() {
        this.textContent = "Привет";
      }
    }
  })
});

В FAST Element регистрация упрощена и структурирована через классы:

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

const template = html<MyComponent>`
  <div>${x => x.greeting}</div>
`;

const styles = css`
  div {
    color: blue;
    font-weight: bold;
  }
`;

export class MyComponent extends FASTElement {
  greeting = "Привет";
}

MyComponent.define({ name: "my-component", template, styles });

Ключевые отличия:

  • Используется современный синтаксис class и ES-модули.
  • Разделение шаблона (template) и стилей (styles).
  • Реактивные свойства, которые автоматически обновляют DOM при изменении значений.

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

В v0 приходилось вручную обновлять DOM при изменении свойств:

this.textContent = this.someProp;

В FAST Element достаточно объявить свойство класса, и любые изменения автоматически отражаются в DOM:

export class MyComponent extends FASTElement {
  someProp = "начальное значение";
}

Для более сложных сценариев можно использовать @observable и реактивные методы:

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

export class MyComponent extends FASTElement {
  @observable
  count = 0;

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

Любое изменение count автоматически обновит все привязки в шаблоне.

События и обработчики

В v0 обработка событий чаще всего требовала явного добавления слушателей в createdCallback или attachedCallback:

this.addEventListener('click', () => console.log('Клик!'));

В FAST Element событие можно привязать прямо в шаблоне:

const template = html<MyComponent>`
  <button @click=${x => x.increment()}>Нажми</button>
  <span>${x => x.count}</span>
`;

Это делает код чище, а обработку событий декларативной.

Shadow DOM и слоты

В Web Components v0 для использования Shadow DOM приходилось явно создавать shadow root:

this.createShadowRoot().innerHTML = `<slot></slot>`;

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

const template = html<MyComponent>`
  <div>
    <slot name="header"></slot>
    <slot></slot>
  </div>
`;

Поддержка именованных и дефолтных слотов полностью совместима со стандартами.

Миграция событий жизненного цикла

В v0 существовали методы createdCallback, attachedCallback, detachedCallback, attributeChangedCallback.

FAST Element использует современные хуки:

  • connectedCallback → вызывается при добавлении элемента в DOM.
  • disconnectedCallback → при удалении.
  • attributeChangedCallback → при изменении атрибутов.
  • propertyChanged → наблюдатели для реактивных свойств.

Пример:

export class MyComponent extends FASTElement {
  count = 0;

  connectedCallback() {
    super.connectedCallback();
    console.log('Компонент подключен');
  }

  countChanged(oldValue, newValue) {
    console.log(`count изменился с ${oldValue} на ${newValue}`);
  }
}

Атрибуты и свойства

В v0 разработчики вручную синхронизировали атрибуты и свойства, что часто приводило к ошибкам.

В FAST Element достаточно объявить свойство с соответствующим типом и реактивностью:

export class MyComponent extends FASTElement {
  @observable
  label = "";

  labelChanged(oldValue, newValue) {
    console.log(`Label изменён: ${newValue}`);
  }
}

Атрибут label автоматически синхронизируется с соответствующим свойством.

Использование шаблонов и повторений

Для создания списков или повторяющихся элементов в v0 приходилось вручную управлять DOM:

this.items.forEach(item => {
  const el = document.createElement('li');
  el.textContent = item;
  this.appendChild(el);
});

В FAST Element это делается декларативно:

const template = html<MyComponent>`
  <ul>
    ${x => x.items.map(item => html`<li>${item}</li>`)}
  </ul>
`;

Любое изменение массива items автоматически обновит DOM.

Структура проекта и модульность

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


Переход с Web Components v0 на FAST Element обеспечивает более чистую архитектуру, реактивность и удобство работы с DOM, упрощает управление состоянием и событиями, а также полностью соответствует современным стандартам браузеров.