Фабричный паттерн в контексте Vue.js применяется для централизованного и предсказуемого создания компонентов. Вместо прямого импорта и регистрации каждого компонента используется функция-фабрика, которая инкапсулирует логику выбора, конфигурации и возврата компонента. Такой подход особенно актуален в приложениях со сложной структурой интерфейса, динамическими сценариями и большим количеством однотипных компонентов.
Ключевая особенность — отделение логики создания компонента от места его использования.
Простейшая фабрика представляет собой функцию, возвращающую компонент в зависимости от входных параметров.
import TextInput from '@/components/inputs/TextInput.vue'
import NumberInput from '@/components/inputs/NumberInput.vue'
import DateInput from '@/components/inputs/DateInput.vue'
export function inputFactory(type) {
switch (type) {
case 'text':
return TextInput
case 'number':
return NumberInput
case 'date':
return DateInput
default:
return null
}
}
Использование фабрики в шаблоне через динамический компонент:
<component :is="currentInputComponent" />
import { inputFactory } from '@/factories/inputFactory'
export default {
props: {
type: String
},
computed: {
currentInputComponent() {
return inputFactory(this.type)
}
}
}
Фабрика может не только возвращать компонент, но и выполнять его регистрацию. Это удобно при использовании глобальных компонентов или плагинов.
import TextInput from '@/components/inputs/TextInput.vue'
import NumberInput from '@/components/inputs/NumberInput.vue'
const registry = {
text: TextInput,
number: NumberInput
}
export function registerInputs(app) {
Object.entries(registry).forEach(([name, component]) => {
app.component(`Input${name}`, component)
})
}
Такой подход упрощает контроль над пространством имён и исключает дублирование кода регистрации.
Фабричный паттерн раскрывается сильнее при добавлении конфигурации. Фабрика может возвращать не просто компонент, а обёрнутый компонент с заранее заданными свойствами.
import BaseButton from '@/components/BaseButton.vue'
export function buttonFactory(options) {
return {
extends: BaseButton,
props: {
...BaseButton.props,
variant: {
type: String,
default: options.variant
}
}
}
}
Использование:
const PrimaryButton = buttonFactory({ variant: 'primary' })
const DangerButton = buttonFactory({ variant: 'danger' })
В результате создаются разные компоненты на базе одного шаблона без дублирования.
Vue поддерживает асинхронную загрузку компонентов, и фабрика позволяет централизовать этот механизм.
export function asyncComponentFactory(loader) {
return () => ({
component: loader(),
delay: 200,
timeout: 3000
})
}
Пример использования:
const UserCard = asyncComponentFactory(() =>
import('@/components/UserCard.vue')
)
Преимущество — единые правила загрузки, таймаутов и обработки ошибок.
Фабрика может учитывать состояние приложения, роли пользователя или данные с сервера.
import AdminPanel from '@/components/AdminPanel.vue'
import UserPanel from '@/components/UserPanel.vue'
export function panelFactory(role) {
if (role === 'admin') {
return AdminPanel
}
return UserPanel
}
В данном случае компонент становится результатом бизнес-решения, а не просто отображением.
Фабричный компонент может заранее определять структуру слотов.
export function layoutFactory(headerComponent, footerComponent) {
return {
components: { headerComponent, footerComponent },
template: `
<div class="layout">
<headerComponent />
<slot />
<footerComponent />
</div>
`
}
}
Это позволяет формировать разные макеты на основе одной фабрики без жёсткой привязки к конкретным компонентам.
Прямой импорт компонентов
Фабричный паттерн
При использовании TypeScript фабрика может возвращать строго типизированные компоненты.
import { DefineComponent } from 'vue'
import TextInput from '@/components/inputs/TextInput.vue'
export function typedFactory(): DefineComponent {
return TextInput
}
Типизация снижает количество ошибок при работе с динамическими компонентами и улучшает автодополнение.
/factories)Фабричный паттерн в Vue.js усиливает модульность, упрощает сопровождение и позволяет строить масштабируемую архитектуру компонентов без избыточной связности.