Как стать автором
Обновить
536.18
OTUS
Цифровые навыки от ведущих экспертов

Коротко про слоты в Vue.js

Уровень сложностиПростой
Время на прочтение3 мин
Количество просмотров5.1K

Привет, Хабр!

Когда ты разрабатываешь интерфейсы на Vue.js, рано или поздно приходит момент, когда простые пропсы уже не спасают. Допустим, нужно сделать компонент не просто гибким, а настолько гибким, чтобы его можно было адаптировать под любые сценарии. Пропсами ты тут не отделаешься. И вот тут могут помочь слоты.

Начнём с простого

Что такое слоты? Это такие места в компоненте, куда можно вставлять разметку. Рассмотрим базовый пример:

<template>
  <div class="card">
    <header>
      Default header
    </header>
    <main>
      Default content
    </main>
    <footer>
      Default footer
    </footer>
  </div>
</template>

Здесь есть три слота: один дефолтный и два именованных. Когда используешь этот компонент, можно легко кастомизировать содержимое, вставив свой контент в нужное место:

<template>
  <card>
    <template #default>
      <h1>Мой кастомный заголовок</h1>
    </template>
    <template #main>
      <p>Это мой кастомный контент.</p>
    </template>
    <template #footer>
      <p>Кастомный футер.</p>
    </template>
  </card>
</template>

Результат — компонент кастомизирован именно так, как нужно. У каждого клиента или задачи может быть своя версия контента, и слоты позволяют сделать компонент универсальным.

Именованные слоты

Когда дело доходит до более сложных интерфейсов, нужны уже именованные слоты. Они помогают не просто передавать контент, а разбрасывать его по нужным местам. Например, есть модальное окно с несколькими зонами (заголовок, тело и футер). И вот как можно это реализовать:

<template>
  <div class="modal">
    <div class="modal-header">
      <slot name="header">Default Modal Header</slot>
    </div>
    <div class="modal-body">
      <slot name="body">Default Body Content</slot>
    </div>
    <div class="modal-footer">
      <slot name="footer">Default Modal Footer</slot>
    </div>
  </div>
</template>

Кастомизация может выглядеть так:

<template>
  <modal>
    <template #header>
      <h2>Кастомный заголовок</h2>
    </template>
    <template #body>
      <p>Кастомное тело модального окна.</p>
    </template>
    <template #footer>
      <button>Кнопка для футера</button>
    </template>
  </modal>
</template>

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

p.s:

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

Scoped Slots

Теперь перейдём к Scoped Slots. С ними можно передавать не просто контент, а логику и данные в компонент.

Представим, что есть компонент, который передаёт в слот данные. Например, список элементов:

<template>
  <div>
    <slot :items="items"></slot>
  </div>
</template>

<script>
export default {
  data() {
    return {
      items: ['Элемент 1', 'Элемент 2', 'Элемент 3']
    };
  }
};
</script>

Теперь можно использовать эти данные для кастомизации компонента:

<template>
  <div>
    <ul>
      <li v-for="item in items" :key="item">{{ item }}</li>
    </ul>
  </div>
</template>

Где может пригодиться: в проектах, когда нужно построить что-то вроде таблицы, где каждая ячейка отображает разные данные в зависимости от логики. Например, можно рендерить разные элементы в зависимости от роли пользователя или состояния приложения.

Динамические компоненты

Допустим, нужно что-то ещё более сложное — компонент, который сам решает, какие слоты ему нужны, и когда. Например, в зависимости от состояния или данных. Здесь помогают динамические компоненты.

Пример:

<template>
  <component :is="dynamicComponent">
    <template #header>Заголовок</template>
    <template #body>Основной контент</template>
  </component>
</template>

<script>
export default {
  data() {
    return {
      dynamicComponent: 'CardComponent'  // Это может быть любое имя компонента
    };
  }
};
</script>

Можно менять компонент динамически, в зависимости от логики приложения.

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


Что дальше?

Если слоты уже не кажутся cложностью, стоит углубиться в такие темы, как:

  • Композиционное API — для более гибкого построения логики компонентов.

  • Рендер-функции — когда нужно ещё больше контроля над тем, как рендерятся компоненты.

23 октября для новичков в Vue.js пройдет открытый урок «Composition API против Options API: что выбрать?». Полученные на уроке знания будут полезны при любом взаимодействии с Vue.js, так как это основы работы. Если интересно — записывайтесь на урок на странице курса «Vue.js разработчик».

Теги:
Хабы:
Всего голосов 12: ↑8 и ↓4+9
Комментарии7

Публикации

Информация

Сайт
otus.ru
Дата регистрации
Дата основания
Численность
101–200 человек
Местоположение
Россия
Представитель
OTUS