логотип PurpleSchool
логотип PurpleSchool

Понимание core функционала Vue и его применение

Автор

Олег Марков

Введение

Vue — это прогрессивный JavaScript-фреймворк, который стал очень популярным благодаря своей простоте и мощности. Если вы только начинаете погружаться в мир Vue или хотите лучше понять, что происходит "под капотом", эта статья даст вам подробный разбор core-функционала: реактивности, компонентов, директив, жизненного цикла и других ключевых аспектов. Здесь вы получите практические советы и узнаете, какие основные возможности предоставляет вам Vue на уровне ядра.

Понимание реактивности во Vue

Как Vue отслеживает и обновляет данные

Главная особенность Vue — его реактивная система. Это значит, что все переменные, которые вы объявляете во Vue, становятся "наблюдаемыми": если их значение изменится, интерфейс автоматически обновится.

Пример:

const { reactive } = Vue

const state = reactive({
  message: 'Привет, мир!'
})

// Когда вы обновите message, Vue сразу отобразит это изменение в интерфете:
state.message = 'Изменено'
// Интерфейс отобразит новый текст

Почему это работает?
Vue использует прокси-объекты (Proxy) для того, чтобы "подслушивать" ваши обращения к данным и реагировать на любые изменения. Вам не нужно явно обновлять DOM — Vue сделает это за вас.

В отличие от других фреймворков

В отличие, например, от React, где нужно вызывать setState или использовать хуки, во Vue вы просто меняете свойство объекта, и всё остальное происходит автоматически.

Использование refs и реактивных объектов

В Composition API часто применяют ref для простых типов и reactive для объектов/массивов.

import { ref, reactive } from 'vue'

const count = ref(0)         // Для примитивов
const user = reactive({      // Для объектов
  name: 'Алексей',
  age: 25
})

// Для count обращайтесь как count.value
count.value++

Это важно помнить: когда вы работаете с ref, данные хранятся внутри value, а reactive делает геттеры прямо на объекте. Смотрите разницу на примере выше.

Ограничения реактивности

Некоторые операции Vue отслеживает не полностью:

  • Добавление новых свойств к уже реактивному объекту (в Vue 2) — такие свойства не будут реактивны.
  • В Vue 3 эти ограничения практически устранены благодаря Proxy, однако, если вы используете массивы и мутируете индексы напрямую, будьте внимательны.

Компоненты: основы, создание и использование

Что такое компонент во Vue

Компоненты — строительные блоки приложений во Vue. Каждый компонент — это самостоятельная часть интерфейса с собственными данными, логикой и шаблоном. Благодаря компонентам вы делите приложение на маленькие управляемые части.

Синтаксис компонента

Давайте создадим простой компонент на Vue 3 с Composition API:

// MyButton.vue
<template>
  <button @click="increment">{{ count }}</button>
</template>

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

const count = ref(0)

function increment() {
  count.value++
}
</script>

Здесь:

  • В шаблоне кнопка отображает счетчик.
  • На каждое нажатие кнопки счетчик увеличивается на 1.

Пропсы и события

Компоненты могут получать данные через пропсы и отправлять события обратно "родителю".

Пример передачи пропсов

// ParentComponent.vue
<template>
  <ChildComponent :title="parentTitle" @clicked="onChildClick"/>
</template>

<script setup>
import { ref } from 'vue'
import ChildComponent from './ChildComponent.vue'

const parentTitle = ref('Заголовок родителя')

function onChildClick() {
  console.log('Клик в дочернем компоненте')
}
</script>

// ChildComponent.vue
<template>
  <button @click="$emit('clicked')">{{ title }}</button>
</template>

<script setup>
defineProps(['title'])
</script>

Смотрите, как работает связь:

  • Родитель передаёт строку через prop title.
  • Дочерний компонент выводит prop и "сообщает" родителю о клике, генерируя событие.

Slot'ы для расширения компонента

Слоты позволяют компонента сделать универсальным и расширяемым. Вместо забитого содержимого, вы "вставляете" нужный HTML снаружи.

// BaseCard.vue
<template>
  <div class="card">
    <slot></slot>
  </div>
</template>

// Использование
<BaseCard>
  <h3>Заголовок карточки</h3>
  <p>Текст внутри карточки</p>
</BaseCard>

Директивы в Vue: расширяя синтаксис шаблонов

Директивы — это специальные инструкции, которые вы добавляете к элементам в шаблоне. Они начинаются с v-.

Наиболее используемые директивы

v-bind

Привязывает динамические значения к атрибутам или свойствам DOM:

<img v-bind:src="imgUrl" alt="Картинка">
// Короткая запись:
<img :src="imgUrl" />

Комментарий:
Если значение imgUrl изменится, ссылка на картинку в интерфейсе тоже изменится автоматически.

v-model

Двусторонняя привязка между значением input и переменной:

<input v-model="username" placeholder="Имя пользователя" />
// username будет автоматически обновляться при вводе, и наоборот

v-if, v-else-if, v-else

Используется для условного отображения (рендеринга) элементов:

<p v-if="isAdmin">Вы администратор</p>
<p v-else>Вы не администратор</p>

v-for

Для цикличного вывода массива данных:

<ul>
  <li v-for="user in users" :key="user.id">{{ user.name }}</li>
</ul>
// users — ваш массив юзеров

Создание пользовательских директив

Иногда стандартных директив может не хватать. Vue позволяет создавать свои:

app.directive('focus', {
  mounted(el) {
    el.focus()
  }
})

// Использование:
<input v-focus />

Комментарий:
Когда элемент "вмонтируется" в DOM, на него автоматически наведётся фокус.

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

Вам часто нужно выполнять действия тогда, когда компонент только появился или был обновлен, или, наоборот, уничтожен. Для этого у компонентов есть lifecycle hooks.

Основные хуки жизненного цикла:

  • onMounted — вызовется после монтирования компонента
  • onUpdated — срабатывает при изменении реактивных данных и перерисовке
  • onUnmounted — когда компонент удаляется из DOM

Пример использования хуков

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

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

onUnmounted(() => {
  console.log('Компонент удален из DOM')
})
</script>

Когда использовать хуки в реальных задачах

  • onMounted — чтобы “запустить” подписку на внешние данные, подписаться на ивенты или сделать API-запрос.
  • onUnmounted — когда нужно удалить слушателей событий или “почистить за собой” (например, остановить таймеры).

Роутинг и управление состоянием

Эти возможности часто находятся вне core, но кратко затронем основы.

Vue Router

Позволяет делать многостраничные приложения (SPA):

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
})
// router передается в createApp на старте приложения

Vuex и Pinia — управление глобальным состоянием

Когда компоненты становятся крупнее, появляется необходимость управлять состоянием в одном месте.

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

import { defineStore } from 'pinia'

export const useUserStore = defineStore('user', {
  state: () => ({
    name: 'Андрей',
    isLoggedIn: false
  }),
  actions: {
    login(name) {
      this.name = name
      this.isLoggedIn = true
    }
  }
})

// В компоненте:
const userStore = useUserStore()
userStore.login('Сергей')

Взаимодействие с асинхронными данными и API

Обычно приложения обращаются к серверу, подгружают данные. Vue не ограничивает вас — используйте любой способ: fetch, axios, что угодно.

Пример загрузки данных в компоненте

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

const posts = ref([])

onMounted(async () => {
  const res = await fetch('https://jsonplaceholder.typicode.com/posts')
  posts.value = await res.json()
})
</script>

<template>
  <ul>
    <li v-for="post in posts" :key="post.id">{{ post.title }}</li>
  </ul>
</template>

Комментарий:

  • Данные загружаются при монтировании компонента, список постов становится доступен и автоматически отображается.

Реактивность и производительность: оптимизация

Vue оптимизирует обновление DOM через Virtual DOM. Но есть вещи, о которых нужно помнить:

  • Ключи в v-for — всегда задавайте уникальные ключи, чтобы Vue быстро понимал, какие элементы изменились.
  • watch и computed — используйте, чтобы реагировать на изменения значений или производить вычисления на основе других реактивных переменных.

Пример использования watch

import { ref, watch } from 'vue'

const counter = ref(0)

watch(counter, (newValue, oldValue) => {
  console.log(`Счетчик изменился с ${oldValue} на ${newValue}`)
})

computed-переменные

Для данных, которые можно вычислить из других данных, используйте computed:

import { ref, computed } from 'vue'

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

const fullName = computed(() => {
  return `${firstName.value} ${lastName.value}`
})
// fullName будет всегда в актуальном состоянии

Инструменты и особенности разработки во Vue

Devtools

Установите Vue Devtools — это расширение для браузера, упрощающее отладку, показ реактивных данных и компонентов "на лету".

SFC — Single File Component

Vue поддерживает компонентный подход, где каждый компонент обычно оформляется в отдельном файле с расширением .vue. Он содержит <template>, <script> и <style>. Такой подход улучшает читаемость кода и масштабируемость проекта.

Динамические компоненты и ленивый импорт

Если у вас много компонентов, не обязательно загружать их все сразу.

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

const AsyncComp = defineAsyncComponent(() =>
  import('./components/BigComponent.vue')
)
</script>

<template>
  <Suspense>
    <template #default>
      <AsyncComp />
    </template>
    <template #fallback>
      <p>Загрузка...</p>
    </template>
  </Suspense>
</template>

Комментарий: Данный подход позволяет уменьшить объем начальной загрузки, подгружая тяжелый компонент только по мере необходимости.

Заключение

Система реактивности, компонентная архитектура, мощные директивы и удобные инструменты жизненного цикла — вот что делает Vue очень удобным и производительным инструментом для создания современных интерфейсов. Вы видели простоту декларативного синтаксиса, а также гибкость расширения, работы с асинхронными данными и управления состоянием. Понимание core-функционала позволит вам строить масштабируемые и поддерживаемые приложения, используя весь потенциал Vue без лишней сложности.

Частозадаваемые технические вопросы по теме статьи и ответы на них

Как правильно "отслеживать" изменения в реактивных объектах внутри массивов?

Если у вас массив объектов и вы хотите отследить изменение в каком-либо объекте, используйте watch с опцией deep:

watch(users, (newUsers) => {
  // Реакция на любые изменения внутри массива или его объектов
}, { deep: true })

Как эффективно передавать функции из родителя в дочерний компонент?

Передавайте функции как пропсы, как обычные данные. В дочернем компоненте их можно вызывать напрямую, или используйте события (emit) для оповещения родителя о действиях.

// В родителе
<MyChild :onSave="handleSave" />

// В дочернем
props: ['onSave']
// Вызов: props.onSave()

Как правильно обращаться к DOM-элементу внутри компонента Vue 3?

С помощью template ref:

<input ref="inputEl" />
import { ref, onMounted } from 'vue'

const inputEl = ref(null)
onMounted(() => {
  inputEl.value.focus()
})

Почему не срабатывают хуки жизненного цикла в некоторых случаях?

Это возможно, если компонент не был смонтирован (например, из-за условия v-if) или используется неправильный синтаксис (например, попытка прописать хуки вне <script setup> в компонентах с Composition API).

Как обработать асинхронную ошибку в onMounted?

Используйте try/catch внутри асинхронной функции в хуке:

onMounted(async () => {
  try {
    await loadData()
  } catch (err) {
    console.error('Ошибка при загрузке:', err)
  }
})
Стрелочка влевоГайд по defineEmits на Vue 3Понимание и применение Composition API в Vue 3Стрелочка вправо

Все гайды по Vue

Руководство по валидации форм во Vue.jsИнтеграция Tiptap для создания редакторов на VueРабота с таблицами во Vue через TanStackИнструкция по установке и компонентам Vue sliderУправление пакетами Vue js с помощью npmУправление пакетами и node modules в Vue проектахКак использовать meta для улучшения SEO на VueПолный гайд по компоненту messages во Vuejs5 правил использования Inertia с Vue и LaravelРабота с модулями и пакетами в VueИнструкция по работе с grid на VueGithub для Vue проектов - подробная инструкция по хранению и совместной работеНастройка ESLint для Vue проектов и поддержка качества кодаОбработка ошибок и отладка в Vue.jsИспользование Vue Devtools для отладки и мониторинга приложенийРабота с конфигурационными файлами и скриптами VueСоздание и настройка проектов Vue с помощью Vue CLI3 способа интеграции Chart.js с Vue для создания графиковРабота с Canvas во VueИнструкция по реализации календаря во VueРабота с Ant Design Vue для создания UI на Vue
Обзор и использование утилит Vue для удобной разработкиРабота с обновлениями компонента и жизненным циклом updateРазрешение конфликтов и ошибок с помощью Vue resolveИспользование query-параметров и их обработка в маршрутах VueЗагрузка и управление состоянием загрузки в VueИспользование библиотек Vue для расширения функционалаРабота с JSON данными в приложениях VueКак работать с экземплярами компонента Instance во VueПолучение данных и API-запросы во Vue.jsЭкспорт и импорт данных и компонентов в VueОбработка событий и их передача между компонентами VuejsГайд по defineEmits на Vue 3Понимание core функционала Vue и его применениеПонимание и применение Composition API в Vue 3Понимание и работа с компилятором VueКогда и как использовать $emit и call во VueВзаимодействие с внешними API через Axios в Vue
Веб приложения на Vue архитектура и лучшие практикиИспользование Vite для быстрого старта и сборки проектов на Vue 3Работа с URL и ссылками в приложениях на VueРабота с пользовательскими интерфейсами и UI библиотеками во VueОрганизация и структура исходных файлов в проектах VueИспользование Quasar Framework для разработки на Vue с готовыми UI-компонентамиОбзор популярных шаблонов и стартовых проектов на VueИнтеграция Vue с PHP для создания динамичных веб-приложенийКак организовать страницы и маршруты в проекте на VueNuxt JS и Vue 3 для SSR приложенийСоздание серверных приложений на Vue с помощью Nuxt jsИспользование Vue Native для разработки мобильных приложенийОрганизация и управление индексной страницей в проектах VueИспользование Docker для контейнеризации приложений на VueИнтеграция Vue.js с Django для создания полноценных веб-приложенийСоздание и работа с дистрибутивом build dist Vue приложенийРабота со стилями и CSS в Vue js для красивых интерфейсовСоздание и структурирование Vue.js приложенияКак исправить ошибку cannot find module vueНастройка и сборка проектов Vue с использованием современных инструментовИнтеграция Vue с Bitrix для корпоративных решенийРазработка административных панелей на Vue js
5 библиотек для создания tree view во VueИнтеграция Tailwind CSS с Vue для современных интерфейсовИнтеграция Vue с серверной частью и HTTPS настройкамиКак обрабатывать async операции с Promise во VueИнтеграция Node.js и Vue.js для разработки приложенийРуководство по интеграции Vue js в NET проектыПримеры использования JSX во VueГайд по импорту и регистрации компонентов на VueМногоязычные приложения на Vue с i18nИнтеграция FLIR данных с Vue5 примеров использования filter во Vue для упрощения разработки3 примера реализации drag-and-drop во Vue
Управление переменными и реактивными свойствами во VueИспользование v for и slot в VueПрименение v-bind для динамической привязки атрибутов в VueУправление пользователями и их данными в Vue приложенияхСоздание и использование UI Kit для Vue приложенийТипизация и использование TypeScript в VuejsИспользование шаблонов в Vue js для построения интерфейсовИспользование Swiper для создания слайдеров в VueРабота со стилями и стилизацией в VueСтруктура и особенности Single File Components SFC в VueРабота со SCSS в проектах на Vue для стилизацииРабота со скроллингом и прокруткой в Vue приложенияхПрименение script setup синтаксиса в Vue 3 для упрощения компонентовИспользование scoped стилей для изоляции CSS в компонентах Vue3 способа улучшить навигацию Vue с push()Обработка запросов и асинхронных операций в VueПонимание и использование provide inject для передачи данных между компонентамиПередача и использование props в Vue 3 для взаимодействия компонентовПередача данных между компонентами с помощью props в Vue jsУправление property и функциями во Vue.jsРабота со свойствами компонентов VueУправление параметрами и динамическими данными во VueРабота с lifecycle-хуком onMounted во VueОсновы работы с объектами в VueПонимание жизненного цикла компонента Vue js на примере mountedИспользование модальных окон modal в Vue приложенияхИспользование методов в компонентах Vue для обработки логикиИспользование метода map в Vue для обработки массивовИспользование хуков жизненного цикла Vue для управления состоянием компонентаРабота с ключами key в списках и компонентах VueОбработка пользовательского ввода в Vue.jsРабота с изображениями и их оптимизация в VueИспользование хуков жизненного цикла в VueОрганизация сеток и гридов для верстки интерфейсов на VueСоздание и управление формами в VueОрганизация файлов и структура проекта Vue.jsКомпоненты Vue создание передача данных события и emitРабота с динамическими компонентами и данными в Vue3 способа манипулирования DOM на VueРуководство по div во VueИспользование директив в Vue и их расширенные возможностиОсновы и применение директив в VueИспользование директив и их особенности на Vue с помощью defineИспользование компонентов datepicker в Vue для выбора датОрганизация циклов и итераций во VueКак работает компиляция Vue CoreСоздание и использование компонентов в Vue JSОбработка кликов и пользовательских событий в VueИспользование классов в Vue для организации кода и компонентовИспользование директивы checked для управления состоянием чекбоксов в VueГайд на checkbox компонент во VueОтображение данных в виде графиков с помощью Vue ChartСоздание и настройка кнопок в VueСоздание и настройка кнопок в Vue приложенияхРабота с lifecycle-хуками beforeCreate и beforeMount во VueИспользование массивов и методов их обработки в VueИспользование массивов и их обработка в Vue
Использование Vuetify для создания современных интерфейсов на VueИспользование transition во VueТестирование компонентов и приложений на VueРабота с teleport для управления DOM во VueПять шагов по настройке SSR в VuejsИспользование Shadcn UI компонентов с Vue для продвинутых интерфейсовИспользование router-link для навигации в Vue RouterКак использовать require в Vue для динамического импорта модулейРабота с динамическим рендерингом и виртуальным DOM на Vue.jsИспользование ref для управления ссылками и реактивностью в Vue 3Использование Vue Pro и его преимущества для профессиональной разработкиРуководство по nextTick для работы с DOMСоздание и использование компонентов с помощью Vue js и CУправление состоянием и реактивностью через inject и provideДинамическое обновление компонентов и данных на VueГлубокое изучение документации Vue и как эффективно её использоватьИспользование Crystal с Vue для разработкиИспользование вычисляемых свойств для динамического отображения данных на Vue jsОптимизация производительности и предупреждения в Vue
Открыть базу знаний