Введение в Vue3

Vue3 — это прогрессивный фреймворк для создания пользовательских интерфейсов.

ПрогрессивныйЭто означает, что вы можете внедрять только часть возможностей Vue в соответствии с потребностями вашего проекта: от простого улучшения взаимодействия на странице до создания полноценных одностраничных приложений (SPA) и даже приложений с серверным рендерингом (SSR) — Vue3 полностью на это способен.

Vue3 — это прогрессивный JavaScript-фреймворк для фронтенда, созданный Эваном Ю, официально выпущенный 18 сентября 2020 года под кодовым названиемOne Piece。

По сравнению с Vue2, Vue3 полностью переписал основную архитектуру: система реактивности перешла отObject.definePropertyобновлена доProxy, с внедрением Composition API и комплексным улучшением производительности, поддержки TypeScript, размера бандла и многого другого.

Официальное позиционирование Vue3:фреймворк, с которым легко начать работу, но который обладает достаточной мощью для поддержки сложных проектов. Он не навязывает конкретную архитектуру, как Angular, и не требует тяжелой ручной оптимизации, как React; вместо этого он соблюдает баланс между простотой использования и возможностями.

Основные различия между Vue3 и Vue2

Vue3 — это не патчевое обновление Vue2, а полная переработка.

Пункт сравненияVue2Vue3
Принцип реактивностиObject.defineProperty, не может отслеживать вновь добавленные свойства и изменения индексов массиваProxy, полностью проксирует все операции над объектом, без вышеуказанных ограничений
Организация кодаOptions API: data, methods и computed разделеныComposition API: код группируется по логическим задачам
Поддержка TypeScriptАдаптирован позже, ограниченный вывод типовОсновной код переписан на TypeScript, TS — полноправный гражданин
Размер бандлаРазмер рантайма примерно 20KB (gzip)Поддерживает Tree-shaking, сборку по требованию, минимум — всего 13.5KB
ПроизводительностьБазовый уровеньНачальный рендеринг примерно на 55% быстрее, рендеринг обновления примерно на 133% быстрее, потребление памяти снижено примерно на 54%
Корневой узел шаблона компонентаДолжен иметь ровно один корневой элементПоддерживает несколько корневых узлов (Fragment)
Глобальный APIМонтируется на конструктор Vue, несколько экземпляров совместно используют состояниеЧерезcreateAppсоздание независимых экземпляров с более тщательной изоляцией

Основные возможности

Улучшения Vue3 охватывают четыре измерения: систему реактивности, дизайн API, компилятор и новые встроенные компоненты.

Composition API

Composition API — самое важное изменение дизайна в Vue3; оно решает фундаментальные проблемы Options API в Vue2:Связанная логика разбросана по разным опциям, что затрудняет повторное использование。

В Options API данные для функции "поиска пользователей" могут быть разбросаны поdata、methods、computed、watchчетырём опциям; тогда как Composition API позволяет написать всю логику для одной и той же возможности вместе, а затем вынести её в переиспользуемые функции (Composables).

Пример: Options API против Composition API

<!-- Подход Options API (поддерживается Vue2 / Vue3) -->
<script>
export default {
  data() {
    return {
count: 0, // данные счётчика
username: 'example' // данные имени пользователя
    }
  },
  computed: {
doubled() { // удвоенное значение count
      return this.count * 2
    }
  },
  methods: {
increment() { // увеличить count
      this.count++
    }
  }
}
</script>

Пример: рекомендуемый подход (синтаксический сахар script setup)

<!-- Composition API + script setup (рекомендуемый подход во Vue 3) -->
<script setup>
import { ref, computed } from 'vue'

// Реактивные данные объявляются напрямую, не нужно возвращать
const count = ref(0) // ref оборачивает примитивные типы
const username = ref('example')

// вычисляемое свойство
const doubled = computed(() => count.value * 2)

// Методы определяются непосредственно как функции
function increment() {
count.value++ // Примечание: к значениям, обёрнутым в ref, нужно обращаться через .value
}
</script>

<template>
  <!-- В шаблонах ref автоматически разворачивается, .value не нужен -->
  <p>Пользователь: {{ username }}</p>
  <p>Количество: {{ count }}, удвоенное: {{ doubled }}</p>
  <button @click="increment">+1</button>
</template>

<script setup>это синтаксический сахар для Composition API: он позволяет<script>напрямую писать код Composition API на верхнем уровне, без необходимости вручнуюreturn, все переменные и функции верхнего уровня автоматически становятся доступны в шаблоне. В настоящее время это наиболее рекомендуемый способ написания однофайловых компонентов во Vue3.

Система реактивности: Proxy заменяет defineProperty

Реактивность Vue2 основана наObject.defineProperty, у этого подхода есть две проблемы, которые невозможно принципиально решить: он не может отслеживать вновь добавленные свойства объекта и не может отслеживать прямое присваивание элементам массива по индексу. Vue3 используетProxyчтобы принципиально решить эти проблемы.

Пример: ref и reactive

import { ref, reactive, watch } from 'vue'

// ref: подходит для примитивных типов (number, string, boolean)
// Для доступа и изменения значений требуется .value
const count = ref(0)
count.value = 10

// reactive: подходит для объектов и массивов
// Доступ к свойствам напрямую, .value не нужен
const user = reactive({
  name: 'EXAMPLE',
  age: 18,
  skills: ['vue', 'typescript']
})

// В Vue3 можно добавлять новые свойства к объекту, и реактивность всё ещё работает нормально
user.email = '[email protected]'  // В Vue2 эта операция не вызывает обновление представления

// Вы также можете изменять элементы массива напрямую
user.skills[0] = 'vue3'  // В Vue2 эта операция не вызывает обновление представления

// Отслеживание изменений реактивных данных
watch(count, (newVal, oldVal) => {
  console.log(`счёт от ${oldVal}до ${newVal}`)
})

Композиционные функции (Composables)

Composables — стандартный способ повторного использования логики с состоянием в Vue3, аналогично пользовательским хукам React.

Принятоuseдавать имени префикс, выносить законченный фрагмент реактивной логики в независимую функцию и повторно использовать её в нескольких компонентах.

Пример: пользовательский Composable

// Путь к файлу: composables/useCounter.js
// Инкапсулируйте логику счётчика; любой компонент может её переиспользовать

import { ref, computed } from 'vue'

export function useCounter(initialValue = 0) {
  const count = ref(initialValue)           // Внутреннее реактивное состояние
  const doubled = computed(() => count.value * 2)  // Производное состояние

  function increment() { count.value++ }
  function decrement() { count.value-- }
  function reset() { count.value = initialValue }

  // Вернуть состояние и методы, которые должны быть доступны извне
  return { count, doubled, increment, decrement, reset }
}

Пример: использование Composable в компонентах

<script setup>
import { useCounter } from './composables/useCounter'

// Деструктурируйте и используйте напрямую; реактивность сохраняется
const { count, doubled, increment, decrement, reset } = useCounter(10)
</script>

<template>
  <p>Текущее значение: {{ count }}, удвоенное: {{ doubled }}</p>
  <button @click="increment">+1</button>
  <button @click="decrement">-1</button>
  <button @click="reset">Сбросить</button>
</template>

Новые встроенные компоненты

Vue3 представляет три новых встроенных компонента, которые решают три часто встречающихся сценария во фронтенд-разработке.

КомпонентРешаемая проблемаТипичные случаи использования
FragmentVue2 требовал, чтобы шаблоны компонентов имели единственный корневой узел; Fragment позволяет нескольким корневым узлам сосуществовать (без дополнительного оборачивающего div)Компоненты элементов списка, сокращающие ненужную вложенность DOM
TeleportОтображает HTML компонента в любой указанной позиции в DOM, преодолевая ограничения контекста наложения CSS родительского компонентаГлобальные модальные диалоги, Toast-уведомления, плавающие панели инструментов
SuspenseИзящно отображает резервное содержимое до завершения загрузки асинхронных компонентов, единообразно обрабатывая состояния асинхронного ожиданияСкелетон-экраны для лениво загружаемых компонентов, индикаторы загрузки во время переходов между маршрутами

Пример: использование Teleport для реализации глобального модального окна

<script setup>
import { ref } from 'vue'
const showModal = ref(false)
</script>

<template>
  <button @click="showModal = true">Открыть модальное окно</button>

  <!--
Teleport монтирует содержимое модального окна под body,
а не внутри родительского элемента текущего компонента, избегая проблем с z-index и overflow
 -->
  <Teleport to="body">
    <div v-if="showModal" class="modal-mask">
      <div class="modal-box">
        <p>Это глобальное модальное окно</p>
        <button @click="showModal = false">Закрыть</button>
      </div>
    </div>
  </Teleport>
</template>

Пример: использование Suspense для обработки асинхронной загрузки компонентов

<!-- Родительский компонент App.vue -->
<template>
  <Suspense>
    <!-- Слот по умолчанию: асинхронное содержимое -->
    <template #default>
      <AsyncUserProfile />  <!-- Асинхронные компоненты, которые внутренне используют await -->
    </template>
    <!-- резервный слот: содержимое, отображаемое во время загрузки -->
    <template #fallback>
      <div class="loading">Загрузка...</div>
    </template>
  </Suspense>
</template>

Поддержка tree-shaking

Vue3 изменяет все глобальные API на именованные экспорты. Благодаря возможности tree-shaking у сборщиков, таких как Vite / webpack, неиспользуемые API не включаются в итоговую сборку.

Пример: импорт API по требованию

// Vue2: Все API доступны через глобальный объект Vue, который не может быть tree-shaken
// Vue.nextTick(...)
// Vue.set(obj, 'key', value)

// Vue3: импорт по требованию; в бандл включаются только фактически используемые функции
import { ref, computed, watch, nextTick, onMounted } from 'vue'

// Импортируются только эти API; неиспользуемые (такие как watchEffect, provide и т. д.) не будут включены в бандл

Хуки жизненного цикла

Все хуки жизненного цикла, соответствующие Composition API Vue3, имеют префиксonи вызываются внутриsetupsetup().

Options API Vue2Vue3 Composition APIМомент срабатывания
beforeCreate— (сам setup заменяет это)До инициализации экземпляра
created— (сам setup заменяет это)Экземпляр создан
beforeMountonBeforeMountПеред монтированием
mountedonMountedСмонтирован, DOM доступен
beforeUpdateonBeforeUpdateПеред обновлением данных и повторным рендерингом DOM
updatedonUpdatedПосле завершения повторного рендеринга DOM
beforeDestroyonBeforeUnmountПеред размонтированием компонента (имя изменено)
destroyedonUnmountedРазмонтирование компонента завершено (имя изменено)

Пример: использование хуков жизненного цикла

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

const timer = ref(null)
const count = ref(0)

// Выполняется после монтирования компонента (можно безопасно манипулировать DOM)
onMounted(() => {
console.log('Component mounted')
// Запустить таймер, который увеличивает count каждую секунду
  timer.value = setInterval(() => {
    count.value++
  }, 1000)
})

// Выполняется при размонтировании компонента (очистите побочные эффекты, чтобы избежать утечек памяти)
onUnmounted(() => {
  clearInterval(timer.value)
console.log('Таймер очищен')
})
</script>

<template>
  <p>Время работы: {{ count }} секунд</p>
</template>

Полная поддержка TypeScript

Основная библиотека Vue3 полностью переписана на TypeScript, обеспечивая точный вывод типов. В сочетании с<script setup lang="ts">, вы можете использовать TypeScript напрямую в однофайловых компонентах без дополнительной настройки.

Пример: использование TypeScript в script setup

<script setup lang="ts">
import { ref, computed } from 'vue'

// Интерфейс, определяющий структуру данных внутри компонента
interface User {
  id: number
  name: string
  email?: string
}

// ref автоматически выводит тип из начального значения, либо его можно указать явно
const user = ref<User>({
  id: 1,
  name: 'EXAMPLE',
})

// defineProps: объявление и вывод типов пропсов
const props = defineProps<{
 title: string       //Обязательно
 count?: number      //Необязательно
}>()

// defineEmits: объявление пользовательских событий и проверка типов
const emit = defineEmits<{
 (e: 'update', value: number): void
 (e: 'close'): void
}>()

const displayName = computed(() => user.value.name.toUpperCase())

function handleUpdate() {
  emit('update', 42)
}
</script>

Области применения

Как полноценная экосистема фронтенд-фреймворка, Vue3 охватывает широкий спектр сценариев: от одностраничных приложений до серверного рендеринга, от веб-приложений до мобильных.

Одностраничные приложения (SPA)

Это самый классический сценарий использования Vue3. В сочетании сVue Router 4для маршрутизации на стороне фронтенда,Pinia(официально рекомендуемая Vue3 библиотека управления состоянием, заменяющая Vuex) для управления глобальным состоянием вы можете создавать полнофункциональные одностраничные приложения.

Типичные типы проектов: корпоративные административные системы, панели мониторинга данных, витрины интернет-магазинов.

Серверный рендеринг (SSR) и генерация статических сайтов (SSG)

Nuxt 3— это full-stack-фреймворк на основе Vue3, глубоко интегрирующий возможности SSR и SSG. Он автоматически берёт на себя сложность серверного рендеринга, позволяя разработчикам создавать SEO-дружественные приложения так же, как при написании обычных Vue-компонентов.

Подходящие сценарии: контентные сайты, блоги, сайты документации, маркетинговые лендинги.

Мобильная разработка и кроссплатформенность

uni-appПоддерживает использование синтаксиса Vue3 для одновременной разработки WeChat Mini Programs, Alipay Mini Programs, H5 и приложений (iOS/Android).Ionic + Vue3подходит для создания качественных гибридных мобильных приложений.

Настольные приложения

Electron + Vue3(через инструментальные цепочки вроде electron-vite) позволяет упаковывать приложения Vue3 в кросс-платформенные десктопные приложения.Tauri + Vue3— популярная альтернатива последних лет, использующая Rust в качестве бэкенда, что даёт меньший размер приложения и лучшую производительность.

Экосистема библиотек UI-компонентов

Экосистема Vue3 предлагает богатый выбор зрелых библиотек компонентов:

Библиотека компонентовПозиционированиеПодходящие сценарии
Element PlusБиблиотека компонентов для настольных ПК, версия Element UI для Vue3Корпоративные административные системы, приложения с интенсивной обработкой данных
Ant Design VueРеализация Ant Design для Vue с продуманными дизайн-спецификациямиСистемы мидл- и бэк-офиса, корпоративные приложения
Vant 4Мобильная библиотека компонентов, лёгкая и высокопроизводительнаяМобильный H5, мини-программы WeChat
Vuetify 3Библиотека компонентов в стиле Material DesignВеб-приложения для конечных пользователей
Naive UIНаписан на TypeScript, с широкими возможностями настройки темыПроекты, требующие глубокой настройки темы
shadcn-vueОснована на Radix UI и Tailwind, набор компонентов для копирования и вставкиПроекты, которые ценят уникальность UI

История разработки

Vue.js вырос из личного проекта в один из трёх ведущих фронтенд-фреймворков мира. Каждая мажорная версия была обусловлена чёткими инженерными потребностями.

Истоки (2013 - 2014)

Vue.js был создан Эваном Ю во время его работы в Google. В 2013 году он изучал опыт разработки на Angular, надеясь извлечь свою любимую часть — механизм обновления представления на основе данных — и убрать части, которые считал слишком громоздкими.

В феврале 2014 года Vue.js 0.8.0 был публично выпущен. Впоследствии он привлёк внимание сообщества Laravel и постепенно стал широко известен в сообществе JavaScript.

Эпоха Vue 1.x (2015)

В октябре 2015 года официально вышел Vue 1.0 под кодовым названием Evangelion. В том же году последовательно вышлиVue Router(2015.08)、Vuex(2015.11)、Vue CLI(декабрь 2015), что ознаменовало превращение Vue из библиотеки уровня представления в полноценный прогрессивный фреймворк.

Эпоха Vue 2.x (2016 - 2020)

В октябре 2016 года вышел Vue 2.0, представив подход с виртуальным DOM (вдохновлённый React), поддержку серверного рендеринга (SSR) и значительно улучшив производительность.

Эпоха Vue 2 была самым быстрым этапом расширения экосистемы Vue: появились библиотеки компонентов, такие как Element UI, возник Nuxt.js, и Vue стал одним из фронтенд-фреймворков с наибольшим числом звёзд на GitHub в мире.

В феврале 2019 года вышел Vue 2.6 под кодовым названием Macross. Это была последняя мажорная версия Vue 2, соединившая прошлое и будущее.

Выпуск Vue 3.0 (2020)

Разработка Vue3 началась в конце 2018 года и заняла около двух лет, пройдя через 30+ RFC (Request for Comments), 2600+ коммитов и 628 PR от 99 участников.

18 сентября 2020 года официально вышла Vue 3.0 под кодовым названием One Piece. Основные изменения:

  • Система реактивности основана наProxyПереписана
  • Представлен Composition API
  • Полная поддержка TypeScript
  • Добавлены Fragment, Teleport, Suspense
  • Поддерживается Tree-shaking, значительно уменьшен размер бандла

Этап созревания экосистемы (2021 - 2022)

ВремяВерсия / СобытиеЗначимость вехи
2021-08Vue 3.2<script setup>Синтаксический сахар официально стабилизировался,<style> v-bindПоддерживает динамическую привязку CSS, стала одной из самых популярных версий Vue 3
2022-02Vue 3 стала версией по умолчаниюНа официальном сайте vue.js и в npmvueВерсия пакета по умолчанию сменилась с 2 на 3, что ознаменовало официальное доминирование экосистемы Vue 3
2022-05Pinia стала официальной рекомендациейПланы Vuex 5 были отложены, Pinia стала официально рекомендованной библиотекой управления состоянием для Vue 3
2022Vue 3.3Улучшена поддержка обобщённых компонентов, улучшенdefinePropsвывод типов, значительно улучшая опыт работы с TypeScript

Этап непрерывной оптимизации (2023 — настоящее время)

ВремяVersionКлючевые особенности
2023-12Vue 3.4Переписан парсер шаблонов (производительность улучшена ~2x), оптимизация реактивной системы (уменьшено количество срабатываний недействительных вычислений),defineModelМакрос официально стабилизирован (упрощает двустороннее связывание v-model)
2024-09Vue 3.5Деструктуризация Reactive Props официально стабилизирована (деструктуризация с сохранением реактивности без toRef),useTemplateRefНовые API, ленивая гидратация SSR
2025 (в разработке)Vue 3.6Интегрированная реактивная система Alien Signals (память отслеживания зависимостей сокращена ~14%), Vapor Mode вошёл в стадию Alpha (полностью пропускает виртуальный DOM, размер бандла уменьшен с 50KB до ~6KB, время монтирования 100,000 компонентов ~100ms)

Vapor ModeЯвляется наиболее важным будущим техническим направлением для Vue 3: благодаря статическому анализу во время компиляции шаблоны компилируются напрямую в точный код нативных манипуляций DOM, полностью минуя процесс создания и diff виртуального DOM. Он может сосуществовать с существующим режимом виртуального DOM и поддерживает постепенную миграцию. В настоящее время поддерживает только<script setup>Composition API; Options API не применим.


Позиция Vue3 среди трёх основных фреймворков

Vue 3, React и Angular — три основных фреймворка в фронтенд-разработке. Понимание их позиций помогает делать более подходящий выбор технологий.

Критерий сравненияVue3React 18+Angular 17+
ПозиционированиеПрогрессивный фреймворк, официально предоставляет маршрутизацию и управление состояниемUI-библиотека, экосистема управляется сообществомПолноценный фреймворк, для всего есть официальные решения
Стиль синтаксисаОднофайловые компоненты (.vue), интуитивный синтаксис шаблоновJSX, написание HTML на JavaScriptКомпоненты + шаблоны + декораторы, высокая степень инженерности
Кривая обученияОтносительно плавная, синтаксис шаблонов близок к HTMLУмеренная, требует понимания ментальных моделей JSX и HooksКрутая, множество концепций (модули, внедрение зависимостей, RxJS)
TypeScriptОсновная библиотека переписана на TS, хорошая поддержкаХорошая, требуется @types/reactTypeScript по умолчанию, глубокая интеграция
ПроизводительностьОтличная мелкозернистая реактивность, точные обновленияХорошо, React 19 Compiler дополнительно оптимизированХорошо, механизм Signals постоянно улучшается
Применимый масштабПодходит для проектов от малых и средних до крупныхВсе масштабы, зрелые кейсы в сверхкрупных проектахКрупные корпоративные проекты, высокие требования к стандартизации команды
Доля на китайском рынкеНаивысшая, широко используется предприятиямиВысокаяОтносительно низкий

В отечественной фронтенд-экосистеме Vue 3 имеет самый высокий уровень использования. Библиотеки компонентов с полной документацией на китайском языке, такие как Element Plus и Ant Design Vue, значительно снизили барьер для внедрения на предприятиях. Если ваша цель — отечественный рынок труда, Vue 3 — один из фреймворков, которые стоит рассмотреть в первую очередь.


Ограничения Vue3

Понимание границ Vue 3 поможет вам принимать более рациональные технические решения.

ОграничениеКонкретное проявлениеРекомендация
Стоимость решения при сосуществовании Options API и Composition APIСосуществуют два стиля API; командам нужно договориться о единых стандартах, иначе стили кода будут несогласованнымиНовые проекты должны единообразно использовать<script setup> + Composition API
Ментальная нагрузка от .value для реактивных данныхrefТребуется в скриптах.value, автоматически разворачивается в шаблонах, новички легко путаютсяИспользуйте плагин Volar, IDE будет давать подсказки; перестанет быть проблемой, как только выработаете привычку
Сложность управления состоянием для больших приложенийПоддержка управления состоянием в Pinia для сверхбольших сценариев с высокой конкурентностью менее зрелая, чем в ReduxДля сверхбольших приложений можно рассмотреть решения Pinia + модульное разделение
Затраты на гидратацию при серверном рендерингеСтраницам SSR требуется "гидратация", инициализация занимает больше времени на слабых устройствахВ Vue 3.5 появился Lazy Hydration, Vapor Mode в Vue 3.6 ещё больше улучшит это
Богатство международной экосистемыПо сравнению с React, активность англоязычного сообщества Vue и ресурсы Stack Overflow немного меньшеОфициальная документация чрезвычайно высокого качества, китайская документация полная, в первую очередь обращайтесь к официальной документации
Другие расширения