Default slot

В Stencil, как и в других современных фреймворках, слоты играют ключевую роль в создании компонента, который может быть гибко использован в различных контекстах. Одним из типов слотов является default slot (или “по умолчанию”), который позволяет передавать содержимое в компонент без явного указания имени слота. Такой механизм обеспечивает большую гибкость и позволяет разрабатывать компоненты с динамичным содержимым.

Основы использования default slot

Слот по умолчанию используется для вставки контента в компонент, если этот контент не был явно определён в других частях компонента. В Stencil слоты реализуются с помощью элемента <slot>, который указывает на место для внедрения внешнего контента.

Пример базового компонента с использованием default slot:

import { Component, h } from '@stencil/core';

@Component({
  tag: 'my-card',
  styleUrl: 'my-card.css',
  shadow: true
})
export class MyCard {
  render() {
    return (
      <div class="card">
        <slot></slot>
      </div>
    );
  }
}

В этом примере компонент my-card содержит слот по умолчанию, который может быть заполняем контентом при его использовании.

Чтобы использовать этот компонент и передать в слот контент, нужно просто вложить элемент внутри тега компонента:

<my-card>
  <p>Это содержимое по умолчанию</p>
</my-card>

Результатом будет компонент, который отображает переданный параграф внутри блока card.

Поведение default slot

Если слот не заполняется содержимым, он остаётся пустым, и результат отобразится как пустой элемент. Важно помнить, что слоты работают только для дочерних элементов, передаваемых в компонент. Например:

<my-card></my-card>

Этот пример не передаст никакого контента в слот, и компонент отобразится как пустой контейнер.

Использование с другими слотами

Stencil поддерживает несколько слотов, что позволяет более гибко управлять содержимым компонента. Для того чтобы использовать несколько слотов, можно указать имя слота с помощью атрибута name. Однако если явно не указано имя, используется слот по умолчанию.

Пример компонента с несколькими слотами:

@Component({
  tag: 'my-card',
  styleUrl: 'my-card.css',
  shadow: true
})
export class MyCard {
  render() {
    return (
      <div class="card">
        <div class="header">
          <slot name="header"></slot>
        </div>
        <div class="body">
          <slot></slot>  <!-- Слот по умолчанию -->
        </div>
      </div>
    );
  }
}

В этом примере есть два слота: один с именем header, а второй — по умолчанию. Чтобы использовать их, нужно передать контент с указанием имени для первого слота и обычный контент для второго:

<my-card>
  <div slot="header">Заголовок карточки</div>
  <p>Основное содержимое карточки</p>
</my-card>

Преимущества использования default slot

  1. Гибкость: С помощью default slot можно создать компоненты, которые могут быть легко адаптированы к различным сценариям. Разработчик может передавать любой контент, не заботясь о том, чтобы использовать именные слоты.

  2. Читаемость и удобство: Использование слота по умолчанию упрощает структуру компонентов, делая код более читабельным и понятным. Это особенно полезно для компонентов, которые часто встраиваются в другие части приложения.

  3. Минимизация кода: Отсутствие необходимости явно указывать имя слота позволяет значительно упростить синтаксис. В случае необходимости можно комбинировать слоты с именами и без них.

Использование с условными выражениями

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

Пример:

@Component({
  tag: 'my-button',
  styleUrl: 'my-button.css',
  shadow: true
})
export class MyButton {
  @Prop() isLoading: boolean = false;

  render() {
    return (
      <button>
        <slot>{this.isLoading ? 'Загрузка...' : 'Нажмите'}</slot>
      </button>
    );
  }
}

В этом примере, если слот не заполнен, будет отображаться текст по умолчанию, который зависит от значения пропса isLoading. Если передать контент в слот, то он будет отображаться вместо текста по умолчанию.

Пример использования default slot с динамическим контентом

Stencil компоненты часто работают с асинхронным контентом, например, данными из API. В таком случае default slot может быть полезен для динамического вставления контента, который меняется во время работы приложения.

@Component({
  tag: 'user-profile',
  styleUrl: 'user-profile.css',
  shadow: true
})
export class UserProfile {
  @State() userData: any;

  componentWillLoad() {
    fetch('/api/user')
      .then(response => response.json())
      .then(data => {
        this.userData = data;
      });
  }

  render() {
    return (
      <div>
        <h1>Профиль пользователя</h1>
        <slot>{!this.userData ? 'Загружаем данные...' : `Привет, ${this.userData.name}`}</slot>
      </div>
    );
  }
}

В данном случае, если данные пользователя ещё не загружены, в слоте будет отображаться текст «Загружаем данные…». После получения данных компонент заменит этот текст на имя пользователя.

Советы по использованию default slot

  1. Минимизация вложенности: Не стоит злоупотреблять множественными вложенными слотами в одном компоненте. Избыточная вложенность может усложнить структуру и сделать компонент трудным в обслуживании.

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

  3. Простота и универсальность: Когда нужно создать универсальный компонент, использование default slot позволит компоненту адаптироваться под различные ситуации, а сам код останется чистым и понятным.

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