Справочник по Vue.js
Область справочника
Справочник-шпаргалка по Vue.js — реактивность, SFC, Composition API, экосистема. Не заменяет пошаговое обучение — курс: раздел Vue. Таблицы синтаксиса и API — для быстрого поиска фактов.
Быстрый старт
npm install vue-router@4
Справочные таблицы
Содержание справочника
- 1. Основные понятия
- 2. Реактивность
- 3. Компоненты
- 4. Директивы
- 5. Жизненный цикл компонента
- 6. Composition API
- 7. Teleport
- 8. Suspense
- 9. Конфигурация приложения
- 10. Плагины
- 11. Типы данных и ограничения
- 12. Маршрутизация (Vue Router)
- 13. Управление состоянием
- 14. Инструменты сборки
- 15. Однофайловые компоненты (.vue)
- 16. Server-Side Rendering (SSR)
- 17. DevTools
- 18. Оптимизации
- 19. Типизация (TypeScript)
- 20. Тестирование
- 21. Best Practices
- 22. Сравнение с другими фреймворками
- 23. Примеры использования
1. Основные понятия
Экземпляр приложения
Все приложения Vue начинаются с создания экземпляра приложения через createApp.
const app = Vue.createApp({
// корневой компонент
})
Метод createApp принимает объект конфигурации корневого компонента и возвращает экземпляр приложения.
Корневой компонент
Корневой компонент определяет начальное состояние и поведение приложения. Он содержит:
data— реактивные данныеmethods— методыcomputed— вычисляемые свойстваwatch— наблюдателиsetup()— точка входа для Composition APItemplateилиrender— шаблон или функция рендеринга
Монтирование
Приложение монтируется в DOM-элемент:
app.mount('#app')
Метод mount принимает селектор или DOM-элемент и заменяет его содержимое отрендеренным представлением компонента.
2. Реактивность
ref
Создаёт реактивную ссылку на примитивное значение.
import { ref } from 'vue'
const count = ref(0)
console.log(count.value) // 0
Значение доступно через .value.
reactive
Создаёт реактивный объект (глубокая реактивность).
import { reactive } from 'vue'
const state = reactive({ count: 0 })
Изменения любого вложенного свойства отслеживаются автоматически.
computed
Создаёт вычисляемое свойство, кэшируемое до изменения зависимостей.
import { computed } from 'vue'
const doubled = computed(() => count.value * 2)
Поддерживает геттер и сеттер:
const fullName = computed({
get() { return firstName.value + ' ' + lastName.value },
set(newValue) { /* разбор newValue */ }
})
watch
Наблюдает за изменениями реактивных данных.
import { watch } from 'vue'
watch(count, (newVal, oldVal) => {
console.log(`count изменился с ${oldVal} на ${newVal}`)
})
Типы наблюдаемых значений:
refreactive- геттер-функция
- массив источников
Опции watch:
immediate: true— запуск немедленноdeep: true— глубокое наблюдение за объектамиflush: 'pre' | 'post' | 'sync'— момент выполнения колбэка
watchEffect
Автоматически отслеживает зависимости и выполняет функцию при их изменении.
import { watchEffect } from 'vue'
watchEffect(() => {
console.log(count.value)
})
Не требует явного указания источника.
3. Компоненты
Определение компонента
Через объект:
const MyComponent = {
props: ['title'],
template: '<h1>{{ title }}</h1>'
}
Через defineComponent (рекомендуется для TypeScript):
import { defineComponent } from 'vue'
const MyComponent = defineComponent({ ... })
Регистрация компонентов
Глобальная:
app.component('MyComponent', MyComponent)
Локальная (внутри компонента):
export default {
components: { MyComponent }
}
Props
Передача данных от родителя к дочернему компоненту.
props: {
title: String,
age: { type: Number, required: true },
isActive: { type: Boolean, default: false }
}
Типы type — String, Number, Boolean, Array, Object, Date, Function, Symbol, null (для любого типа).
Опции:
required: truedefault: valueилиdefault() { return ... }validator(value) { return condition }
Emits
Объявление событий, которые может выбросить компонент.
emits: ['update:title', 'submit']
С проверкой типов:
emits: {
submit: (payload) => typeof payload === 'object'
}
Выброс события:
emit('submit', data)
Slots
Передача контента в компонент.
По умолчанию:
<my-component>Контент слота</my-component>
Именованные слоты:
<my-component>
<template #header>Заголовок</template>
<template #footer>Подвал</template>
</my-component>
Scoped slots (слоты с данными):
<my-component v-slot="{ user }">
{{ user.name }}
</my-component>
Внутри компонента:
<slot :user="currentUser"></slot>
provide / inject
Передача данных через дерево компонентов без пропсов.
Провайдер:
import { provide } from 'vue'
provide('theme', 'dark')
Инжектор:
import { inject } from 'vue'
const theme = inject('theme', 'light') // 'light' — значение по умолчанию
Работает с ref и reactive — реактивность сохраняется.
4. Директивы
Встроенные директивы
v-bind
Привязка атрибутов или свойств.
<img v-bind:src="imageSrc" />
<!-- сокращённо -->
<img :src="imageSrc" />
Модификаторы:
.prop— привязка как DOM-свойство.attr— привязка как атрибут.camel— преобразование kebab-case в camelCase
v-on
Обработка событий.
<button v-on:click="handleClick">Клик</button>
<!-- сокращённо -->
<button @click="handleClick">Клик</button>
Модификаторы:
.stop— остановка всплытия.prevent— предотвращение действия по умолчанию.capture— обработка на фазе перехвата.self— только если событие от самого элемента.once— однократное срабатывание.passive— пассивный обработчик- Клавиатурные:
.enter,.esc,.space,.up,.downи т.д. - Мышь:
.left,.right,.middle
v-if / v-else-if / v-else
Условный рендеринг.
<div v-if="isVisible">Видим</div>
<div v-else>Скрыт</div>
v-show
Переключение видимости через CSS display.
<div v-show="isVisible">Всегда в DOM</div>
v-for
Рендеринг списков.
<li v-for="item in items" :key="item.id">{{ item.name }}</li>
С индексом:
<li v-for="(item, index) in items" :key="index">{{ index }}: {{ item }}</li>
Можно использовать с объектами:
<span v-for="(value, key, index) in object" :key="key">
{{ index }}. {{ key }}: {{ value }}
</span>
v-model
Двусторонняя привязка данных.
На <input>:
<input v-model="message" />
Эквивалентно:
<input :value="message" @input="message = $event.target.value" />
Модификаторы:
.lazy— синхронизация поchange, а неinput.number— автоматическое преобразование в число.trim— удаление пробелов по краям
На компонентах:
<custom-input v-model="searchText" />
Внутри компонента:
props: ['modelValue'],
emits: ['update:modelValue'],
template: `<input :value="modelValue" @input="$emit('update:modelValue', $event.target.value)" />`
v-text / v-html
Установка текстового или HTML-содержимого.
<span v-text="msg"></span>
<div v-html="rawHtml"></div>
⚠️ v-html не очищает содержимое — уязвимость XSS при использовании ненадёжных данных.
v-cloak
Скрывает неразобранные шаблоны до инициализации Vue.
<div v-cloak>{{ message }}</div>
Требует CSS:
[v-cloak] { display: none; }
5. Жизненный цикл компонента
Options API хуки
beforeCreatecreatedbeforeMountmountedbeforeUpdateupdatedbeforeUnmountunmounted
Composition API аналоги
onBeforeMountonMountedonBeforeUpdateonUpdatedonBeforeUnmountonUnmountedonErrorCapturedonRenderTrackedonRenderTriggered
Пример:
import { onMounted } from 'vue'
onMounted(() => {
console.log('Компонент смонтирован')
})
6. Composition API
setup()
Основная функция компонента в Composition API.
Параметры:
props— реактивные пропсыcontext— объект сattrs,slots,emit,expose
Возврат:
- объект с переменными и методами, доступными в шаблоне
- функция рендеринга
setup(props, { emit }) {
const count = ref(0)
const increment = () => {
count.value++
emit('change', count.value)
}
return { count, increment }
}
expose()
Ограничивает публичный API компонента при обращении через $refs.
setup(props, { expose }) {
const publicMethod = () => { ... }
expose({ publicMethod })
}
7. Teleport
Рендеринг содержимого вне иерархии DOM компонента.
<teleport to="body">
<div>Модальное окно</div>
</teleport>
Полезно для модалок, тултипов, всплывающих окон.
8. Suspense
Обработка асинхронных зависимостей (например, async setup).
<Suspense>
<template #default>
<AsyncComponent />
</template>
<template #fallback>
<div>Загрузка...</div>
</template>
</Suspense>
Компонент с async setup:
async setup() {
const data = await fetchData()
return { data }
}
9. Конфигурация приложения
app.config
errorHandler
Глобальный обработчик ошибок.
app.config.errorHandler = (err, instance, info) => {
console.error('Ошибка:', err, info)
}
warnHandler
Обработчик предупреждений.
globalProperties
Добавление глобальных свойств (аналог $ в Vue 2).
app.config.globalProperties.$http = axios
optionMergeStrategies
Настройка стратегий слияния опций.
performance
Включение метрик производительности (только в dev-режиме).
10. Плагины
Подключение через app.use(plugin, options).
Плагин — функция или объект с методом install.
const MyPlugin = {
install(app, options) {
app.directive('focus', ...)
app.provide('config', options)
}
}
app.use(MyPlugin, { apiKey: '123' })
11. Типы данных и ограничения
Поддерживаемые типы реактивности
- Примитивы —
string,number,boolean,bigint,symbol - Объекты —
Object,Array,Map,Set,WeakMap,WeakSet - Встроенные —
Date,RegExp,Promise
Ограничения
- Свойства, добавленные после создания реактивного объекта, не являются реактивными (используй
Vue.setв Vue 2, в Vue 3 этого нет — всё реактивно благодаря Proxy) - Индексы массива нельзя отслеживать напрямую — используй
splice,push,popи другие мутации - Прямое присваивание по индексу работает в Vue 3
12. Маршрутизация (Vue Router)
Установка
npm install vue-router@4
Базовая настройка
Код ITЗагрузка примера кода…
Динамические сегменты
{ path: '/user/:id', component: User }
Доступ через route.params.id.
Вложенные маршруты
{
path: '/user/:id',
component: User,
children: [
{ path: 'profile', component: UserProfile },
{ path: 'posts', component: UserPosts }
]
}
Требует <router-view /> внутри шаблона User.
Именованные маршруты
{ path: '/user/:id', name: 'user', component: User }
Использование:
<router-link :to="{ name: 'user', params: { id: 123 }}">Профиль</router-link>
Программная навигация
router.push('/about')
router.push({ name: 'user', params: { id: 1 } })
router.replace({ path: '/login' })
router.go(-1) // назад
Глобальные хуки
router.beforeEach(to, from, next)— защита маршрутовrouter.afterEach(to, from)— аналитика, скролл
Meta-поля
{ path: '/admin', component: Admin, meta: { requiresAuth: true } }
Проверка в beforeEach:
if (to.meta.requiresAuth && !isAuthenticated) next('/login')
Lazy-loading компонентов
{ path: '/about', component: () => import('./views/About.vue') }
13. Управление состоянием
Pinia (официальная библиотека для Vue 3)
Установка
npm install pinia
Создание хранилища
import { createPinia } from 'pinia'
app.use(createPinia())
Определение store
Код ITЗагрузка примера кода…
Использование в компоненте
import { useCounterStore } from '@/stores/counter'
const store = useCounterStore()
store.increment()
Особенности Pinia:
- Поддержка TypeScript без boilerplate
- Отсутствие мутаций (только действия)
- Модульность без вложенности
- Поддержка SSR
Vuex (устаревший, но поддерживаемый)
Структура
state— данныеgetters— вычисляемые свойстваmutations— синхронные измененияactions— асинхронные операцииmodules— модульность
14. Инструменты сборки
Vite (рекомендуется для Vue 3)
Создание проекта
npm create vue@latest
Преимущества
- Мгновенный запуск dev-сервера
- Нативная поддержка ES-модулей
- Hot Module Replacement (HMR)
- Встроенная поддержка TypeScript, JSX, CSS препроцессоров
Vue CLI (устаревший)
Поддерживается, но не рекомендуется для новых проектов.
15. Однофайловые компоненты (.vue) и <script setup> API
Ниже — практический конспект по спецификации SFC и API <script setup>. Официальная база:
Обзор
Single-File Component (SFC) — это файл .vue, где вместе живут шаблон, логика и стили:
<template>
<button @click="inc">{{ count }}</button>
</template>
<script setup lang="ts">
import { ref } from 'vue'
const count = ref(0)
const inc = () => count.value++
</script>
<style scoped>
button { cursor: pointer; }
</style>
Языковые секции
<template>— разметка компонента (template syntax Vue).<script>— обычный script-блок (Options API илиsetup()).<script setup>— compile-time sugar для Composition API.<style>— стили компонента (scoped,module,lang).<custom-block>— кастомные блоки (например,<i18n>через плагин).
Автоматическое определение name
Для SFC имя компонента может выводиться автоматически по имени файла (например, UserCard.vue -> UserCard), что улучшает DevTools, warnings и keep-alive include/exclude.
Если нужно зафиксировать имя явно, используйте defineOptions({ name: 'CustomName' }).
Пре-процессоры
SFC поддерживает препроцессоры в блоках:
lang="ts"/lang="tsx"для script.lang="scss"/lang="sass"/lang="less"/lang="stylus"для style.lang="pug"для template (при наличии плагина).
Импорты через src
У блоков может быть src, если нужно вынести содержимое:
<template src="./template.html"></template>
<script src="./logic.ts"></script>
<style src="./styles.scss"></style>
Используется редко: обычно удобнее держать SFC целиком в одном файле для читаемости и навигации.
Комментарии
- HTML-комментарии в
<template>могут попадать в итоговую разметку в dev-режиме. - JS/TS-комментарии в
<script>и<script setup>работают обычно. - Для документации API компонента лучше использовать JSDoc над
defineProps,defineEmits, composables и публичными методами.
Базовый синтаксис
Минимальный SFC:
<template>
<h1>{{ title }}</h1>
</template>
<script setup>
const title = 'Hello Vue'
</script>
<script setup> автоматически экспортирует bindings в шаблон. Не нужен return из setup().
Реактивность
В <script setup> используются стандартные примитивы Vue:
import { ref, reactive, computed, watch } from 'vue'
refдля примитивов и ссылок.reactiveдля объектов.computedдля мемоизированных производных значений.watch/watchEffectдля реакций на изменения.
Использование компонентов
Импортированный компонент сразу доступен в шаблоне:
<script setup>
import UserCard from './UserCard.vue'
</script>
<template>
<UserCard />
</template>
Локальная регистрация через components: { ... } не нужна.
Использование пользовательских директив
Для локальных директив в <script setup> действует соглашение vName:
<script setup>
const vFocus = {
mounted(el) {
el.focus()
}
}
</script>
<template>
<input v-focus />
</template>
defineProps() и defineEmits()
Compiler macros для описания входного/выходного контракта компонента:
const props = defineProps<{
title: string
page?: number
}>()
const emit = defineEmits<{
(e: 'change', page: number): void
}>()
- работают только внутри
<script setup>. - не требуют импорта.
- аргументы анализируются компилятором.
defineModel()
Макрос для объявления v-model без ручного modelValue + update:modelValue:
const model = defineModel<string>({ default: '' })
Для нескольких v-model:
const title = defineModel<string>('title')
const checked = defineModel<boolean>('checked')
defineExpose()
Явно задаёт публичный API компонента для родителя через ref:
function reset() {
// ...
}
defineExpose({ reset })
defineOptions()
Позволяет описать опции компонента прямо в <script setup>:
defineOptions({
name: 'UserCard',
inheritAttrs: false
})
defineSlots()
Типизация слотов (особенно полезно в TS):
defineSlots<{
default(props: { highlighted: boolean }): any
footer(): any
}>()
useSlots() и useAttrs()
useSlots()— доступ к объекту слотов в runtime.useAttrs()— доступ к$attrs(атрибуты/слушатели, не описанные вprops/emits).
import { useAttrs, useSlots } from 'vue'
const slots = useSlots()
const attrs = useAttrs()
Использование вместе с обычной секцией <script>
Допустимо иметь и <script>, и <script setup> в одном SFC:
<script>— одноразовые module-level эффекты или named exports.<script setup>— логика экземпляра компонента.
Не дублируйте один и тот же API в обоих блоках без необходимости.
Верхнеуровневый await
<script setup> поддерживает top-level await:
<script setup>
const profile = await fetch('/api/profile').then(r => r.json())
</script>
Чаще используется вместе с Suspense или SSR/SSG-фреймворками (например, Nuxt).
Операторы импорта
В <script setup> работают обычные ESM-импорты:
- статические
import ... from ... - динамические
await import(...) - type-only
import type { ... } from ...(TS)
Также поддерживаются compiler transforms (например, reactivity transform в legacy-проектах), но для новых проектов лучше оставаться на явных ref/.value.
Дженерики
Для generic-компонентов используется атрибут generic:
<script setup lang="ts" generic="T extends { id: string }">
const props = defineProps<{
items: T[]
}>()
</script>
Это помогает создавать переиспользуемые таблицы/селекты/списки с точной типизацией.
Ограничения
- Макросы (
defineProps,defineEmits,defineModel,defineExpose,defineOptions,defineSlots) работают только в<script setup>. - Макросы обрабатываются на этапе компиляции: их нельзя вызывать условно или динамически.
src-импорты блоков ухудшают локальность кода и усложняют поддержку; используйте осознанно.- Top-level
awaitповышает связность с async-рендерингом; учитывайте UX fallback-состояний. - При смешении
<script>и<script setup>легко получить дублирование ответственности — сохраняйте чёткое разделение module-level и instance-level логики.
16. Server-Side Rendering (SSR)
Vue + Vite SSR
Официальный подход через create-vue с флагом SSR.
Nuxt.js
Фреймворк поверх Vue для SSR, генерации статики, мета-тегов.
17. DevTools
Vue DevTools
Браузерное расширение для:
- Инспекции компонентов
- Просмотра состояния (Pinia/Vuex)
- Отслеживания событий
- Профилирования производительности
Поддерживает Vue 3, Pinia, маршруты.
18. Оптимизации
Lazy-loading компонентов
const AsyncComponent = defineAsyncComponent(() =>
import('./components/HeavyComponent.vue')
)
keep-alive
Кэширование компонентов при переключении.
<keep-alive>
<component :is="currentView" />
</keep-alive>
Атрибуты:
include/exclude— список имёнmax— максимальное число кэшируемых экземпляров
v-memo (Vue 3.2+)
Мемоизация поддерева при рендере.
<div v-for="item in list" :key="item.id" v-memo="[item.id === selected]">
{{ item.name }}
</div>
Обновляет DOM только если изменяется условие в массиве.
Компиляция шаблонов
Vue компилирует шаблоны в функции рендеринга. В production-сборке отключается проверка типов и предупреждения.
19. Типизация (TypeScript)
defineComponent
Обеспечивает правильную типизацию опций.
import { defineComponent } from 'vue'
export default defineComponent({
props: { msg: String },
setup(props) {
// props.msg — string | undefined
}
})
defineProps / defineEmits (в <script setup>)
const props = defineProps<{
msg: string
}>()
const emit = defineEmits<{
(e: 'change', id: number): void
}>()
withDefaults
Значения по умолчанию для props в TS:
const props = withDefaults(defineProps<{
size?: 'small' | 'medium' | 'large'
}>(), {
size: 'medium'
})
20. Тестирование
Vitest + Vue Test Utils
Официальный стек для unit-тестов.
Пример:
import { mount } from '@vue/test-utils'
import MyComponent from './MyComponent.vue'
test('renders message', () => {
const wrapper = mount(MyComponent, {
props: { message: 'Hello' }
})
expect(wrapper.text()).toContain('Hello')
})
Cypress / Playwright
Для end-to-end тестирования.
21. Best Practices
- Используйте Composition API для сложной логики
- Разделяйте логику на composable-функции (
useXxx) - Избегайте глубокой вложенности компонентов
- Используйте
keyвv-forдля уникальной идентификации - Не мутируйте props напрямую
- Используйте
v-modelс модификаторами для контроля ввода - Минимизируйте использование глобальных переменных
- Разделяйте представление и бизнес-логику
22. Сравнение с другими фреймворками
| Характеристика | Vue | React | Angular |
|---|---|---|---|
| Парадигма | Декларативная | Декларативная | Декларативная |
| Реактивность | Автоматическая | Через setState / Hooks | Zone.js + ChangeDetection |
| Шаблоны | HTML-based | JSX | HTML + специальные синтаксисы |
| Кривая обучения | Низкая | Средняя | Высокая |
| Размер | ~30 КБ (gzip) | ~40 КБ (с React DOM) | >100 КБ |
| TypeScript | Полная поддержка | Родная поддержка | Встроен |
23. Примеры использования
Простой счётчик
<script setup>
import { ref } from 'vue'
const count = ref(0)
const increment = () => count.value++
</script>
<template>
<button @click="increment">{{ count }}</button>
</template>
Форма с валидацией
Код ITЗагрузка примера кода…
Список с фильтрацией
Код ITЗагрузка примера кода…
В подборках
Статья входит в тематические подборки и блок "С чего начать?" на главной. Соседние шаги того же маршрута:
Справочники — Справочник по React, Справочник по Angular, Справочник по Node, Справочник по TypeScript, Справочник по JavaScript, Справочник по Ext JS.