Element Plus предоставляет богатый набор компонентов для разработки интерфейсов на Vue 3, однако при работе с крупными проектами часто возникает необходимость создать собственный слой абстракции. Такой слой позволяет централизовать настройку компонентов, стандартизировать стили и поведение, а также упростить поддержку приложения.
Унификация внешнего вида и поведения компонентов Каждый компонент может иметь множество настроек и пропсов. Создание оберток позволяет определить единый стиль для кнопок, форм, таблиц, модальных окон и других элементов, избегая повторения кода.
Инкапсуляция бизнес-логики Компоненты Element Plus часто требуют дополнительной логики: обработка событий, валидация данных, работа с API. Обертки позволяют вынести эту логику из компонентов интерфейса в отдельный слой.
Упрощение миграций и обновлений При обновлении Element Plus или смене дизайна достаточно изменить обертку, не трогая весь проект. Это снижает риск ошибок и ускоряет разработку.
/components
├─ ui
│ ├─ UiButton.vue
│ ├─ UiInput.vue
│ ├─ UiSelect.vue
│ └─ UiTable.vue
├─ layout
│ ├─ Header.vue
│ ├─ Sidebar.vue
│ └─ Footer.vue
└─ modal
├─ ConfirmModal.vue
└─ FormModal.vue
ui содержит универсальные элементы
интерфейса.layout объединяет компоненты разметки
страницы.modal отвечает за модальные окна с типовыми
сценариями использования.<template>
<el-button
:type="type"
:size="size"
:loading="loading"
:disabled="disabled"
@click="$emit('click', $event)"
>
<slot></slot>
</el-button>
</template>
<script setup>
import { defineProps, defineEmits } from 'vue';
const props = defineProps({
type: { type: String, default: 'primary' },
size: { type: String, default: 'medium' },
loading: { type: Boolean, default: false },
disabled: { type: Boolean, default: false }
});
const emit = defineEmits(['click']);
</script>
Преимущества такой обертки:
Element Plus предоставляет ElForm и ElFormItem, но логика валидации часто повторяется. Можно создать обертку, которая автоматически подключает стандартные правила.
<template>
<el-form :model="model" :rules="rules" ref="formRef" label-width="120px">
<slot></slot>
</el-form>
</template>
<script setup>
import { ref, defineProps } from 'vue';
const props = defineProps({
model: { type: Object, required: true },
rules: { type: Object, default: () => ({}) }
});
const formRef = ref(null);
const validate = async () => {
try {
await formRef.value.validate();
return true;
} catch {
return false;
}
};
export { validate, formRef };
</script>
Возможности:
Для ElTable часто создается компонент, который добавляет пагинацию, сортировку и фильтры по умолчанию.
<template>
<el-table :data="data" border>
<slot></slot>
</el-table>
<el-pagination
v-if="pagination"
:current-page="pagination.page"
:page-size="pagination.size"
:total="pagination.total"
@current-change="$emit('page-change', $event)"
/>
</template>
<script setup>
import { defineProps, defineEmits } from 'vue';
const props = defineProps({
data: { type: Array, default: () => [] },
pagination: { type: Object, default: null }
});
const emit = defineEmits(['page-change']);
</script>
Преимущества:
Обертка для модальных окон позволяет стандартизировать поведение
ElDialog и уведомлений ElMessage, включая
анимации, кнопки и глобальные обработчики.
import { ElMessage, ElMessageBox } from 'element-plus';
export const notifySuccess = (msg) => {
ElMessage({
message: msg,
type: 'success',
duration: 3000
});
};
export const confirmDialog = async (msg) => {
try {
await ElMessageBox.confirm(msg, 'Подтверждение', {
confirmButtonText: 'Да',
cancelButtonText: 'Нет',
type: 'warning'
});
return true;
} catch {
return false;
}
};
Эффекты:
Использовать слоты для гибкости Позволяет сохранять возможность кастомизации компонентов при сохранении базовых настроек.
Выносить повторяющуюся логику в композиционные
функции Например, useFormValidation,
useTablePagination, useNotification. Это
упрощает повторное использование и тестирование.
Централизованно управлять стилями Через SCSS-переменные или глобальные классы, чтобы внешний вид компонентов оставался единым.
Соблюдать единый паттерн именования Например,
все обертки начинаются с Ui, модальные окна — с
Modal. Это повышает читаемость и поддерживаемость
проекта.
Слой абстракции над Element Plus повышает масштабируемость проекта, облегчает поддержку интерфейса и делает код более предсказуемым. Правильная организация оберток и функций позволяет создавать комплексные приложения без потери контроля над стилем и логикой компонентов.