Переиспользуемые компоненты

Переиспользуемые компоненты позволяют создавать универсальные элементы интерфейса, которые могут использоваться в разных частях приложения без дублирования кода. В Element Plus это особенно актуально, так как библиотека предоставляет широкий набор готовых UI-компонентов, которые можно адаптировать под различные задачи с помощью слотов, пропсов и событий.


Использование слотов для гибкой кастомизации

Слоты — основной механизм для создания переиспользуемых компонентов. Они позволяют вставлять содержимое внутрь компонента извне.

<template>
  <el-card>
    <slot name="header"></slot>
    <slot></slot>
  </el-card>
</template>
  • Именованные слоты (name="header") позволяют определять различные части компонента отдельно.
  • Слот по умолчанию используется для основного содержимого.

Пример использования:

<custom-card>
  <template #header>
    <h3>Заголовок карточки</h3>
  </template>
  Основное содержимое карточки
</custom-card>

Такой подход позволяет один и тот же компонент custom-card использовать для разных типов данных, не создавая новые компоненты для каждого случая.


Пропсы: управление поведением и внешним видом

Пропсы обеспечивают передачу данных в компонент, делая его конфигурируемым.

<template>
  <el-button :type="type" :disabled="disabled">
    <slot></slot>
  </el-button>
</template>

<script setup>
defineProps({
  type: {
    type: String,
    default: 'primary'
  },
  disabled: {
    type: Boolean,
    default: false
  }
})
</script>
  • Дефолтные значения упрощают переиспользование, так как компонент можно использовать даже без указания всех пропсов.
  • Типизация пропсов повышает стабильность при интеграции с TypeScript.

Применение:

<custom-button type="success">Сохранить</custom-button>
<custom-button :disabled="true">Отмена</custom-button>

Передача событий через $emit

Для полноценного переиспользуемого компонента важно обрабатывать взаимодействие с пользователем. В Element Plus компоненты часто используют события (@click, @change), которые можно передавать через $emit.

<template>
  <el-input v-model="inputValue" @input="$emit('update:modelValue', inputValue)"/>
</template>

<script setup>
import { ref, watch } from 'vue';

const props = defineProps({
  modelValue: String
});

const inputValue = ref(props.modelValue);

watch(() => props.modelValue, (newVal) => {
  inputValue.value = newVal;
});
</script>

Такой подход делает компонент совместимым с v-model и позволяет легко переиспользовать его в разных формах.


Комбинирование Element Plus компонентов в один универсальный

Для более сложных UI можно создавать обертки вокруг нескольких компонентов Element Plus. Например, комбинированный фильтр с el-select и el-input:

<template>
  <div class="filter-container">
    <el-select v-model="selectedOption" placeholder="Выберите категорию">
      <el-option
        v-for="item in options"
        :key="item.value"
        :label="item.label"
        :value="item.value"
      />
    </el-select>
    <el-input v-model="searchText" placeholder="Поиск..." @input="onSearch"/>
  </div>
</template>

<script setup>
import { ref, watch } from 'vue';

const props = defineProps({
  options: Array
});
const emit = defineEmits(['search']);

const selectedOption = ref(null);
const searchText = ref('');

const onSea rch = () => {
  emit('search', { category: selectedOption.value, query: searchText.value });
};
</script>
  • Универсальный компонент может быть использован на разных страницах с разными наборами опций.
  • Все внутренние события централизованно передаются наружу через emit.

Переиспользование стилей и классов

Element Plus поддерживает SCSS-переменные и классы, которые можно использовать для создания единого стиля компонентов:

<template>
  <el-button class="primary-button">Кнопка</el-button>
</template>

<style scoped lang="scss">
.primary-button {
  background-color: $--color-primary;
  border-radius: 8px;
  font-weight: bold;
}
</style>
  • Использование переменных $--color-primary и других из Element Plus обеспечивает согласованность интерфейса.
  • Создание CSS-классов для переиспользуемых компонентов уменьшает дублирование кода и облегчает поддержку.

Динамические компоненты и слоты с v-for

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

<template>
  <div>
    <custom-card v-for="item in items" :key="item.id">
      <template #header>
        {{ item.title }}
      </template>
      {{ item.description }}
    </custom-card>
  </div>
</template>

<script setup>
const items = [
  { id: 1, title: 'Карточка 1', description: 'Описание 1' },
  { id: 2, title: 'Карточка 2', description: 'Описание 2' }
];
</script>
  • Каждый экземпляр компонента адаптируется под конкретные данные.
  • Можно легко добавлять новые карточки без изменения структуры компонента.

Интеграция с глобальными настройками Element Plus

Element Plus позволяет настраивать глобальные компоненты и их переиспользуемые версии через app.use(ElementPlus, { locale, size }). Это полезно для переиспользуемых компонентов:

  • Глобальный размер: все кнопки и поля ввода можно стандартизировать.
  • Локализация: переиспользуемые компоненты автоматически подхватывают язык интерфейса.
  • Глобальные миксины и утилиты: можно добавлять методы для общих операций, доступные в любом переиспользуемом компоненте.

Вывод

Переиспользуемые компоненты в Element Plus строятся на комбинации слотов, пропсов, событий и глобальных настроек, что позволяет создавать гибкие, масштабируемые и поддерживаемые элементы интерфейса. Их правильная структура сокращает дублирование кода и повышает согласованность пользовательского интерфейса.