← Назад к курсу

Учебное пособие по Vue.js 3

Это структурированное учебное пособие по Vue.js 3 с фокусом на Composition API. Материал подойдёт как для начинающих, так и для тех, кто переходит с Options API.

Содержание

  1. Введение
  2. Установка и настройка проекта
  3. Основы: шаблоны, директивы, реактивность
  4. Computed properties и Watchers
  5. Жизненный цикл компонента
  6. Компоненты и передача данных (props / emits)
  7. Слоты (slots)
  8. Работа с формами (v-model)
  9. Маршрутизация – Vue Router 4
  10. Управление состоянием – Pinia
  11. Композиция и пользовательские хуки (composables)
  12. Что дальше?

1. Введение

Vue.js — прогрессивный JavaScript-фреймворк для создания пользовательских интерфейсов.
Vue 3 принёс:

  • Composition API (лучшая организация кода в сложных компонентах)
  • Улучшенную реактивность (Proxy)
  • Более быструю производительность
  • Поддержку TypeScript «из коробки»

2. Установка и настройка проекта

Рекомендуемый способ: Vite (быстрая сборка).

npm create vue@latest

При создании выберите нужные опции (TypeScript, Vue Router, Pinia, ESLint и др.).

После установки:

cd my-project
npm install
npm run dev

Для быстрого прототипа можно подключить Vue через CDN:

<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>

3. Основы: шаблоны, директивы, реактивность

3.1. Реактивные переменные

Composition API в компоненте:

<script setup>
import { ref } from 'vue'

const count = ref(0) // реактивная ссылка

function increment() {
  count.value++   // .value – обязательно в JS
}
</script>

<template>
  <button @click="increment">{{ count }}</button>
  <!-- в шаблоне .value не нужен -->
</template>

ref() работает с любыми типами. Для объектов можно использовать reactive().

3.2. Основные директивы

  • v-bind: или : – динамический атрибут
  • v-on: или @ – обработчик события
  • v-if / v-else-if / v-else – условный рендеринг
  • v-for – списки
  • v-model – двустороннее связывание (см. раздел 8)

Пример:

<template>
  <div v-if="visible">Видимый блок</div>
  <ul>
    <li v-for="item in items" :key="item.id">{{ item.name }}</li>
  </ul>
</template>

4. Computed properties и Watchers

4.1. Computed (вычисляемые свойства)

<script setup>
import { ref, computed } from 'vue'

const firstName = ref('Иван')
const lastName = ref('Петров')

const fullName = computed(() => `${firstName.value} ${lastName.value}`)
</script>

Computed автоматически пересчитывается при изменении зависимостей и кешируется.

4.2. Watchers (отслеживание изменений)

<script setup>
import { ref, watch } from 'vue'

const count = ref(0)

watch(count, (newVal, oldVal) => {
  console.log(`Было ${oldVal}, стало ${newVal}`)
})
</script>

5. Жизненный цикл компонента

В Composition API хуки вызываются внутри setup (или <script setup>):

<script setup>
import { onMounted, onUpdated, onUnmounted } from 'vue'

onMounted(() => {
  console.log('Компонент смонтирован')
})

onUnmounted(() => {
  console.log('Компонент уничтожен')
})
</script>

Основные хуки: onBeforeMount, onMounted, onBeforeUpdate, onUpdated, onBeforeUnmount, onUnmounted.


6. Компоненты и передача данных (props / emits)

6.1. Передача данных от родителя к ребёнку (props)

Ребёнок (Child.vue):

<script setup>
const props = defineProps(['title', 'count'])
// или с валидацией:
// defineProps({
//   title: String,
//   count: { type: Number, required: true }
// })
</script>

<template>
  <h2>{{ title }}</h2>
  <p>Счётчик: {{ count }}</p>
</template>

Родитель:

<Child title="Заголовок" :count="42" />

6.2. Отправка событий наверх (emits)

Ребёнок:

<script setup>
const emit = defineEmits(['update'])

function handleClick() {
  emit('update', 'новое значение')
}
</script>

Родитель:

<Child @update="handleUpdate" />

7. Слоты (slots)

Позволяют передавать разметку в компонент.

Компонент Card.vue:

<template>
  <div class="card">
    <header><slot name="header">По умолчанию</slot></header>
    <main><slot /></main>
    <footer><slot name="footer" /></footer>
  </div>
</template>

Использование:

<Card>
  <template #header>Мой заголовок</template>
  <p>Основной контент</p>
  <template #footer>Подвал</template>
</Card>

8. Работа с формами (v-model)

Двустороннее связывание с ref:

<script setup>
import { ref } from 'vue'

const name = ref('')
const isActive = ref(false)
const selectedOption = ref('')
</script>

<template>
  <input v-model="name" placeholder="Введите имя" />
  <input type="checkbox" v-model="isActive" />
  <select v-model="selectedOption">
    <option value="1">Опция 1</option>
    <option value="2">Опция 2</option>
  </select>
</template>

Кастомный v-model на компоненте можно реализовать через modelValue prop и update:modelValue событие.


9. Маршрутизация – Vue Router 4

Установка: npm install vue-router@4

Файл router/index.js

import { createRouter, createWebHistory } from 'vue-router'
import HomePage from '../views/HomePage.vue'
import AboutPage from '../views/AboutPage.vue'

const routes = [
  { path: '/', component: HomePage },
  { path: '/about', component: AboutPage }
]

const router = createRouter({
  history: createWebHistory(),
  routes
})

export default router

В App.vue:

<template>
  <nav>
    <router-link to="/">Главная</router-link>
    <router-link to="/about">О нас</router-link>
  </nav>
  <router-view /> <!-- место рендера текущего компонента -->
</template>

10. Управление состоянием – Pinia

Pinia – официальный стейт-менеджер для Vue 3.

Установка: npm install pinia

Создание store (stores/counter.js):

import { defineStore } from 'pinia'
import { ref } from 'vue'

export const useCounterStore = defineStore('counter', () => {
  const count = ref(0)
  function increment() {
    count.value++
  }
  return { count, increment }
})

Использование в компоненте:

<script setup>
import { useCounterStore } from '@/stores/counter'

const counter = useCounterStore()
</script>

<template>
  <p>{{ counter.count }}</p>
  <button @click="counter.increment">+1</button>
</template>

11. Композиция и пользовательские хуки (composables)

Composable – функция, которая использует реактивные API Vue и переиспользует логику.

Пример composable useMouse.js:

import { ref, onMounted, onUnmounted } from 'vue'

export function useMouse() {
  const x = ref(0)
  const y = ref(0)

  function update(event) {
    x.value = event.clientX
    y.value = event.clientY
  }

  onMounted(() => window.addEventListener('mousemove', update))
  onUnmounted(() => window.removeEventListener('mousemove', update))

  return { x, y }
}

Использование в компоненте:

<script setup>
import { useMouse } from './useMouse'
const { x, y } = useMouse()
</script>

<template>Координаты мыши: {{ x }}, {{ y }}</template>

12. Что дальше?

  • Официальная документация: vuejs.org
  • Инструменты: Vue Devtools, Volar (VS Code плагин)
  • TypeScript + Vue – добавит строгую типизацию
  • Тестирование: Vitest (unit), Cypress (e2e)
  • Серверный рендеринг: Nuxt 3 (фреймворк на основе Vue)

Примечание: Весь код в пособии использует Composition API с <script setup> – это современный стандарт. Все примеры самодостаточны и могут быть скопированы в проект для проверки.