Wrapper-компоненты в Element Plus представляют собой оболочки над стандартными UI-компонентами, позволяющие расширять их функциональность, унифицировать стили и упрощать повторное использование в проектах. Они создаются на базе Vue 3 Composition API и обеспечивают прозрачное взаимодействие с внутренними элементами библиотеки.
Простейший пример Wrapper-компонента — обёртка над
ElButton:
<template>
<el-button :type="type" :size="size" @click="handleClick">
<slot></slot>
</el-button>
</template>
<script setup>
import { defineProps, defineEmits } from 'vue';
import { ElButton } from 'element-plus';
const props = defineProps({
type: {
type: String,
default: 'primary'
},
size: {
type: String,
default: 'medium'
}
});
const emit = defineEmits(['click']);
function handleClick(event) {
emit('click', event);
}
</script>
Ключевые моменты:
ElButton).defineEmits
позволяет перехватывать события и при необходимости добавлять
собственную логику.Wrapper-компоненты часто нужны для внедрения повторяемой логики или кастомных стилей. Например, добавим логику подтверждения перед выполнением действия кнопки:
<template>
<el-button :type="type" :size="size" @click="confirmClick">
<slot></slot>
</el-button>
</template>
<script setup>
import { defineProps, defineEmits } from 'vue';
import { ElButton, ElMessageBox } from 'element-plus';
const props = defineProps({
type: { type: String, default: 'primary' },
size: { type: String, default: 'medium' }
});
const emit = defineEmits(['click']);
async function confirmClick(event) {
try {
await ElMessageBox.confirm('Вы уверены?', 'Подтверждение');
emit('click', event);
} catch {
// Отмена
}
}
</script>
Особенности:
ElMessageBox для подтверждения
действия.Wrapper-компоненты часто применяются для стандартизации форм.
Например, создание единого FormInput:
<template>
<el-form-item :label="label" :prop="prop">
<el-input v-model="modelValue" :placeholder="placeholder" />
</el-form-item>
</template>
<script setup>
import { defineProps, defineEmits } from 'vue';
import { ElFormItem, ElInput } from 'element-plus';
const props = defineProps({
modelValue: String,
label: String,
prop: String,
placeholder: String
});
const emit = defineEmits(['update:modelValue']);
function updateValue(value) {
emit('update:modelValue', value);
}
</script>
Преимущества:
Wrapper-компоненты полезны и для комплексных элементов, например, таблиц:
<template>
<el-table :data="tableData" style="width: 100%">
<el-table-column v-for="col in columns" :key="col.prop" :prop="col.prop" :label="col.label" />
<slot name="actions"></slot>
</el-table>
</template>
<script setup>
import { defineProps } from 'vue';
import { ElTable, ElTableColumn } from 'element-plus';
const props = defineProps({
tableData: { type: Array, default: () => [] },
columns: { type: Array, default: () => [] }
});
</script>
Особенности:
Для сложных интерфейсов удобно передавать данные между
Wrapper-компонентами с помощью provide/inject:
// FormWrapper.vue
<template>
<el-form :model="formData">
<slot></slot>
</el-form>
</template>
<script setup>
import { reactive, provide } from 'vue';
import { ElForm } from 'element-plus';
const formData = reactive({});
provide('formData', formData);
</script>
// FormInputWrapper.vue
<template>
<el-form-item :label="label">
<el-input v-model="formData[prop]" />
</el-form-item>
</template>
<script setup>
import { inject, defineProps } from 'vue';
import { ElFormItem, ElInput } from 'element-plus';
const props = defineProps({ label: String, prop: String });
const formData = inject('formData');
</script>
Преимущества:
Wrapper-компоненты в Element Plus позволяют строить чистые, масштабируемые и повторно используемые интерфейсы, объединяя преимущества готовых компонентов и возможность внедрять кастомную логику без дублирования кода.