В Vuetify, как и в Vue.js, Render functions
представляют собой альтернативу стандартной шаблонной разметке
(template) для описания структуры компонентов. Они
позволяют полностью контролировать процесс генерации виртуального DOM,
обеспечивая гибкость, которую сложно достичь с помощью обычных шаблонов.
Render functions используются как для создания сложных динамических
интерфейсов, так и для оптимизации производительности.
Render function в Vue 2 и Vue 3 имеет схожий синтаксис, но небольшие различия в API. Основная форма выглядит так:
export default {
render(h) {
return h('v-btn', { props: { color: 'primary' } }, 'Нажми меня')
}
}
Здесь h — это сокращение от createElement,
функция для генерации виртуальных узлов (VNode). В Vue 3 синтаксис может
использовать стрелочные функции:
export default {
render() {
return h('v-btn', { color: 'primary' }, 'Нажми меня')
}
}
Ключевые моменты синтаксиса:
'div',
'v-btn' или другой компонент).props), событиями (on), классами
(class) и стилями (style).Vuetify предоставляет компоненты, которые обычно используются в
шаблонах через <v-btn> или
<v-card>. В render functions эти компоненты можно
подключать напрямую:
import { VBtn } from 'vuetify/lib/components'
export default {
components: { VBtn },
render(h) {
return h(VBtn, { props: { color: 'success', outlined: true } }, 'Кнопка')
}
}
Особенности передачи свойств:
props — для передачи свойств компонента Vuetify
(color, outlined, dense и
др.).attrs — для обычных HTML-атрибутов (id,
title).on — для обработки событий (click,
mouseenter).Render functions особенно полезны при динамическом формировании интерфейса. Например, создание списка кнопок на основе массива:
export default {
data() {
return {
buttons: [
{ text: 'Сохранить', color: 'primary' },
{ text: 'Отмена', color: 'error' },
{ text: 'Удалить', color: 'warning' }
]
}
},
render(h) {
return h('div', this.buttons.map(btn =>
h('v-btn', { props: { color: btn.color } }, btn.text)
))
}
}
Здесь каждая кнопка создаётся на лету, что невозможно сделать в
стандартном шаблоне без дополнительных v-for и
v-bind.
Render functions дают полный контроль над слотами компонентов Vuetify:
import { VCard, VCardTitle, VCardText } from 'vuetify/lib/components'
export default {
components: { VCard, VCardTitle, VCardText },
render(h) {
return h(VCard, [
h(VCardTitle, 'Заголовок карточки'),
h(VCardText, 'Содержимое карточки с использованием render function')
])
}
}
Для динамических или именованных слотов используется объект
scopedSlots:
render(h) {
return h(VCard, {
scopedSlots: {
default: props => h('div', `Привет, ${props.name}`)
}
})
}
Обработка событий через render functions выглядит следующим образом:
render(h) {
return h('v-btn', {
props: { color: 'primary' },
on: {
click: () => alert('Кнопка нажата!')
}
}, 'Нажми меня')
}
Можно объединять on и nativeOn, если
требуется различать события DOM и компонента.
Render functions легко интегрируются с Composition API. Например:
import { defineComponent, h, ref } from 'vue'
import { VBtn } from 'vuetify/lib/components'
export default defineComponent({
setup() {
const count = ref(0)
return () => h(VBtn, {
props: { color: 'secondary' },
onClick: () => count.value++
}, `Нажато ${count.value} раз`)
}
})
Здесь render function возвращается напрямую из setup,
что делает компонент полностью функциональным и реактивным.
props, on и
scopedSlots.props и on, чтобы
избежать проблем с передачей данных и событий.Render functions являются мощным инструментом для работы с Vuetify, предоставляя гибкость, динамичность и контроль, который недоступен через стандартные шаблоны.