В Element Plus render-функции предоставляют гибкий
способ создания компонентов и управления их разметкой программно, минуя
традиционные шаблоны template. Это особенно полезно, когда
требуется динамическая генерация сложных структур или управление
поведением компонентов на основе условий во время выполнения.
Render-функция — это обычная функция JavaScript, которая возвращает
VNode (виртуальный узел), описывающий структуру DOM. В
Element Plus и Vue 3 используется функция h из Vue для
создания этих виртуальных узлов.
import { h } from 'vue';
import { ElButton } from 'element-plus';
export default {
setup() {
return () =>
h(ElButton, { type: 'primary', onClick: () => alert('Clicked!') }, 'Нажми меня');
}
};
Здесь ключевые моменты:
h принимает три аргумента: тип
компонента, объект с props/атрибутами, и дочерние элементы.h, что позволяет строить иерархические
структуры.Render-функции особенно эффективны при создании повторяющихся структур с различными свойствами. Например, генерация списка кнопок с разными типами:
import { h } from 'vue';
import { ElButton } from 'element-plus';
const types = ['primary', 'success', 'warning', 'danger'];
export default {
setup() {
return () =>
h('div', {}, types.map(type =>
h(ElButton, { type, style: { margin: '0 8px' } }, type)
));
}
};
Преимущества такого подхода:
В Element Plus компоненты часто имеют слоты, например
ElTable, ElForm, ElSelect.
Render-функции позволяют передавать слоты программно с помощью объекта
slots:
import { h } from 'vue';
import { ElTable, ElTableColumn } from 'element-plus';
const data = [
{ name: 'Иван', age: 28 },
{ name: 'Мария', age: 32 }
];
export default {
setup() {
return () =>
h(ElTable, { data }, {
default: () => [
h(ElTableColumn, {
prop: 'name',
label: 'Имя',
width: 120
}),
h(ElTableColumn, {
prop: 'age',
label: 'Возраст',
width: 80
})
]
});
}
};
Особенности работы со слотами через render-функции:
В render-функциях доступ к событиям и реактивным данным Vue
сохраняется полностью. Можно использовать ref и
reactive для управления состоянием:
import { h, ref } from 'vue';
import { ElInput, ElButton } from 'element-plus';
export default {
setup() {
const inputValue = ref('');
return () =>
h('div', [
h(ElInput, {
modelValue: inputValue.value,
'onUpdate:modelValue': val => inputValue.value = val,
placeholder: 'Введите текст'
}),
h(ElButton, {
type: 'primary',
onClick: () => console.log(inputValue.value)
}, 'Отправить')
]);
}
};
Ключевые моменты:
modelValue и
onUpdate:modelValue заменяет директиву
v-model.Render-функции позволяют полностью использовать преимущества JavaScript для условного рендеринга:
import { h, ref } from 'vue';
import { ElButton } from 'element-plus';
export default {
setup() {
const loggedIn = ref(false);
return () =>
h('div', [
loggedIn.value
? h(ElButton, { type: 'success' }, 'Выйти')
: h(ElButton, { type: 'primary' }, 'Войти')
]);
}
};
Преимущества:
Element Plus предоставляет гибкие компоненты, которые поддерживают глубокую кастомизацию через render-функции. Например, пользовательский рендер ячеек таблицы:
import { h } from 'vue';
import { ElTable, ElTableColumn } from 'element-plus';
const data = [
{ name: 'Алексей', score: 95 },
{ name: 'Ольга', score: 82 }
];
export default {
setup() {
return () =>
h(ElTable, { data }, {
default: () => [
h(ElTableColumn, {
prop: 'name',
label: 'Имя'
}),
h(ElTableColumn, {
prop: 'score',
label: 'Баллы',
// Пользовательский рендер через render-функцию
vSlots: {
default: ({ row }) => h('span', {
style: { color: row.score > 90 ? 'green' : 'orange' }
}, row.score)
}
})
]
});
}
};
Особенности:
Render-функции в Element Plus позволяют сочетать мощь реактивного Vue 3 с гибкостью программной генерации компонентов, обеспечивая полную свободу в построении интерфейсов и логики компонентов.