Декоратор @Component

Декоратор @Component является важнейшим элементом фреймворка Stencil. Он используется для аннотирования классов, чтобы указать, что они должны быть компонентами, которые Stencil будет обрабатывать и рендерить. Этот декоратор позволяет связывать класс с метаданными, такими как селектор компонента, стиль, свойства и события.

Синтаксис использования

Декоратор @Component применяется непосредственно перед классом компонента. Он принимает объект с настройками, которые описывают компонент и его поведение в рамках Stencil-приложения.

@Component({
  tag: 'my-component',
  styleUrl: 'my-component.css',
  shadow: true,
})
export class MyComponent {
  // Логика компонента
}

В данном примере класс MyComponent будет обработан фреймворком как компонент с тегом <my-component>, который будет использовать CSS-файл my-component.css для стилизации. Опция shadow: true указывает, что компонент будет использовать теневой DOM.

Параметры декоратора @Component

  1. tag (string) Указывает имя HTML-тега, который будет ассоциирован с компонентом. Это имя компонента в разметке. Например, если tag задан как 'my-component', то компонент будет использоваться как <my-component> в разметке HTML.

    @Component({
      tag: 'my-component'
    })
    export class MyComponent {}
  2. styleUrl (string | string[]) Путь к стилям компонента. Он может быть одним или несколькими путями к CSS-файлам. Эти файлы будут использоваться для стилизации компонента.

    @Component({
      tag: 'my-component',
      styleUrl: 'my-component.css'
    })
    export class MyComponent {}
  3. styleTarget (string) Определяет, где применять стили компонента. Допустимыми значениями являются:

    • shadow — стили будут применяться внутри теневого DOM.
    • document — стили будут применяться ко всему документу.
    @Component({
      tag: 'my-component',
      styleUrl: 'my-component.css',
      styleTarget: 'document'
    })
    export class MyComponent {}
  4. shadow (boolean) Указывает, следует ли использовать теневой DOM для компонента. Если shadow установлено в true, компонент будет иметь собственный изолированный DOM, что помогает избежать конфликтов стилей и обеспечивает инкапсуляцию.

    @Component({
      tag: 'my-component',
      shadow: true
    })
    export class MyComponent {}
  5. listeners (Array) Позволяет определять обработчики событий для компонентов. Это массив объектов, каждый из которых описывает событие, которое будет слушать компонент. Событие может быть связано с элементом компонента или с его shadow DOM.

    @Component({
      tag: 'my-component',
      listeners: [
        {
          event: 'click',
          target: 'document',
          handler: 'handleClick'
        }
      ]
    })
    export class MyComponent {
      handleClick(event: Event) {
        console.log('Document clicked');
      }
    }
  6. readOnly (boolean) Если этот параметр установлен в true, то компонент будет работать в режиме “только для чтения”. Это означает, что его свойства и методы не могут изменяться извне. Это полезно для оптимизации производительности, когда требуется, чтобы компонент не изменял свои данные в ответ на пользовательские действия.

    @Component({
      tag: 'my-component',
      readOnly: true
    })
    export class MyComponent {
      property: string = 'initial value';
    }

Инкапсуляция стилей

Stencil поддерживает два типа инкапсуляции стилей для компонентов: теневой DOM и глобальные стили.

  1. Теневой DOM Когда используется теневой DOM (параметр shadow: true), стили компонента ограничиваются его внутренним контекстом. Это предотвращает влияние внешних стилей на компонент и позволяет ему сохранять независимость от глобальных стилей.

    @Component({
      tag: 'my-component',
      styleUrl: 'my-component.css',
      shadow: true
    })
    export class MyComponent {}

    В этом случае, стили, указанные в styleUrl, будут применяться только к элементам внутри теневого DOM. Это помогает изолировать компонент от других частей приложения.

  2. Глобальные стили Если компонент не использует теневой DOM, его стили будут глобальными. Это может быть полезно, если нужно, чтобы стили компонента применялись к элементам за его пределами. В Stencil можно указать глобальные стили в отдельном файле или внутри компонента.

Использование свойств и методов

Декоратор @Component также предоставляет возможность работы с данными и методами компонента через систему свойств и событий.

  1. Свойства Свойства компонента могут быть связаны с аттрибутами HTML, и их изменения будут автоматически отражаться в DOM. Например, если компонент имеет свойство name, его можно использовать в разметке:

    @Component({
      tag: 'my-component'
    })
    export class MyComponent {
      @Prop() name: string;
    }

    В этом примере свойство name будет доступно как аттрибут в разметке:

    <my-component name="John"></my-component>
  2. Методы Методы компонента могут быть использованы для выполнения логики внутри компонента. С помощью декоратора @Method можно явно экспортировать методы компонента, чтобы они были доступны из родительского компонента.

    @Component({
      tag: 'my-component'
    })
    export class MyComponent {
      @Method() async doSomething() {
        // Метод для выполнения действия
      }
    }

Пример

Ниже приведен пример компонента с использованием декоратора @Component, который включает все основные настройки.

@Component({
  tag: 'user-card',
  styleUrl: 'user-card.css',
  shadow: true,
  listeners: [
    {
      event: 'click',
      target: 'document',
      handler: 'handleClick'
    }
  ]
})
export class UserCard {
  @Prop() userId: number;
  @State() user: { name: string, email: string };

  componentWillLoad() {
    this.loadUserData();
  }

  async loadUserData() {
    const response = await fetch(`/api/user/${this.userId}`);
    this.user = await response.json();
  }

  handleClick(event: Event) {
    console.log('Card clicked', event);
  }

  render() {
    return (
      <div>
        <h2>{this.user?.name}</h2>
        <p>{this.user?.email}</p>
      </div>
    );
  }
}

В этом примере компонент UserCard загружает данные о пользователе по ID и отображает их. Он использует теневой DOM, слушает события кликов на документе и позволяет передавать аттрибут userId через HTML.

Заключение

Декоратор @Component является мощным инструментом для создания компонентов в Stencil. Он предоставляет гибкие настройки, позволяя детально контролировать поведение компонента, его стилизацию, инкапсуляцию и взаимодействие с внешним миром.