Компонент во Vue — это изолированная, переиспользуемая часть интерфейса, объединяющая разметку, логику и стили. Компоненты позволяют строить приложение как иерархию независимых блоков, каждый из которых отвечает за строго определённую функциональность. Архитектура на основе компонентов упрощает поддержку кода, тестирование и масштабирование.
Компонент во Vue всегда представляет собой JavaScript-объект с
определённым набором опций или функцию, возвращающую этот объект. На
практике чаще всего используются однофайловые компоненты
(.vue), но возможны и другие формы.
Однофайловый компонент состоит из трёх логических частей:
<template>
<div class="counter">
<button @click="increment">{{ count }}</button>
</div>
</template>
<script>
export default {
data() {
return {
count: 0
}
},
methods: {
increment() {
this.count++
}
}
}
</script>
<style scoped>
.counter {
padding: 10px;
}
</style>
<template>Содержит декларативную HTML-разметку, расширенную директивами Vue. Разметка должна иметь один корневой элемент (или фрагмент в Vue 3).
<script>Описывает логику компонента: состояние, методы, вычисляемые свойства, хуки жизненного цикла. Экспорт по умолчанию — обязательное требование.
<style>Определяет стили компонента. Атрибут scoped ограничивает
область применения CSS текущим компонентом.
Компонент может быть объявлен без использования .vue
файла:
const MyComponent = {
template: '<p>{{ message }}</p>',
data() {
return {
message: 'Пример компонента'
}
}
}
Такой способ применяется в небольших примерах, песочницах или при использовании Vue без сборщика.
Локальная регистрация ограничивает область видимости компонента текущим родительским компонентом. Это основной и рекомендуемый подход.
import ChildComponent from './ChildComponent.vue'
export default {
components: {
ChildComponent
}
}
После регистрации компонент можно использовать в шаблоне:
<child-component />
Глобально зарегистрированный компонент доступен во всех компонентах приложения без явного импорта.
import { createApp } from 'vue'
import App from './App.vue'
import BaseButton from './components/BaseButton.vue'
const app = createApp(App)
app.component('BaseButton', BaseButton)
app.mount('#app')
Глобальная регистрация оправдана для базовых UI-компонентов (кнопки, иконки, модальные окна).
import UserCard from './UserCard.vue'
<user-card />
Vue автоматически сопоставляет UserCard и
user-card. Использование PascalCase в шаблонах допустимо
при работе с .vue файлами, но kebab-case остаётся
универсальным стандартом.
Асинхронные компоненты загружаются только при необходимости, снижая размер начального бандла.
const AsyncComponent = () => import('./AsyncComponent.vue')
export default {
components: {
AsyncComponent
}
}
import { defineAsyncComponent } from 'vue'
const AsyncComponent = defineAsyncComponent({
loader: () => import('./AsyncComponent.vue'),
loadingComponent: LoadingSpinner,
errorComponent: LoadError,
delay: 200,
timeout: 3000
})
При использовании setup регистрация компонентов не
меняется:
import ExampleItem from './ExampleItem.vue'
export default {
components: {
ExampleItem
},
setup() {
const value = ref(0)
return { value }
}
}
Composition API влияет на организацию логики, но не на механизм регистрации.
Vue позволяет рендерить компонент динамически с помощью специального элемента:
<component :is="currentComponent" />
export default {
data() {
return {
currentComponent: 'ComponentA'
}
},
components: {
ComponentA,
ComponentB
}
}
Значение is может быть строкой, объектом компонента или
функцией.
В проектах со сборщиками возможно автоматическое подключение компонентов:
const modules = import.meta.glob('./components/*.vue', { eager: true })
export default {
components: Object.fromEntries(
Object.entries(modules).map(([path, module]) => {
const name = path.split('/').pop().replace('.vue', '')
return [name, module.default]
})
)
}
Такой подход уменьшает объём ручного кода, но требует строгой структуры проекта.
Компонент может вызывать сам себя, если задано имя:
export default {
name: 'TreeNode',
props: {
node: Object
}
}
<tree-node
v-for="child in node.children"
:key="child.id"
:node="child"
/>
Имя компонента используется для разрешения рекурсии.
props и
событияКомпоненты остаются независимыми единицами, даже будучи глобально доступными.
Неправильное имя компонента
<UserCard /> <!-- не работает без поддержки PascalCase -->
Отсутствие экспорта
const Component = { /* ... */ } // нет export default
Использование без регистрации
<unknown-component />
Конфликт имён при глобальной регистрации
Компоненты формируют основу архитектуры Vue-приложения:
Грамотная регистрация компонентов напрямую влияет на читаемость, производительность и масштабируемость кода.