Перейти к основному содержимому

Первая программа на Vue.js

Разработчику Архитектору

Play ITЗагрузка интерактивного демо…


Первая программа на Vue.js

Где применяют Vue

Vue — фреймворк для интерфейса в браузере. Вы описываете страницу почти обычным HTML, а Vue сам обновляет экран, когда меняются данные. Ручной поиск элементов в DOM и textContent = … для каждой кнопки не нужен — это и есть реактивность.

В React разметка чаще живёт в JS (JSX). Во Vue привычнее шаблон <template> с директивами — v-model, v-if, v-for, @click. После HTML/CSS многим так проще войти в SPA.


Рекомендуемый порядок

Если вы только заходите во Vue, держитесь последовательности:

  1. ref и простые кнопки.
  2. v-model и v-if.
  3. v-for со списком.
  4. onMounted + fetch.

Так вы по шагам закрываете весь базовый цикл клиентского приложения.

В этой статье одно приложение разберём по шагам:

  1. Счётчик и имяref, директивы, стили в .vue.
  2. Список заметок с Node APIonMounted и fetch.
  3. Дочерний компонент — props и события вверх.
  4. Options API — как пишут в legacy-проектах.

Обзор экосистемы: Vue.js. Склейка с API: Fullstack 264. Сравнение: React 272 · Angular 292.


Что получится

ЧастьРезультат
Проектcreate vue + Vite → http://localhost:5173
UIПриветствие, счётчик, (опционально) список с сервера
ФайлыApp.vue и при желании components/Counter.vue
APIGET http://127.0.0.1:3000/notes, если Node запущен

Создание проекта

Нужен Node.js (LTS с nodejs.org):

node -v
npm -v

Разбор:

  • node -v показывает установленную версию Node.js и проверяет, что среда выполнения JavaScript доступна в системе.
  • npm -v выводит версию пакетного менеджера npm, через который устанавливаются зависимости Vue-проекта.
  • Команды помогают сразу выявить проблему окружения до создания проекта, а не в середине установки.
  • Если одна из команд не находится, нужно добавить Node.js в PATH или переустановить LTS-версию.
npm create vue@latest my-first-vue-app
cd my-first-vue-app
npm install
npm run dev

Разбор:

  • npm create vue@latest my-first-vue-app генерирует каркас приложения Vue 3 с актуальными шаблонами.
  • cd my-first-vue-app открывает контекст проекта, чтобы установка и запуск выполнялись по нужным путям.
  • npm install подтягивает все библиотеки, включая vue, vite и служебные dev-зависимости.
  • npm run dev запускает локальный сервер разработки; адрес обычно выводится в терминале.
  • На этом шаге формируется полный цикл локальной разработки — создать, установить, запустить.
Вопрос мастераНа первый раз
TypeScriptпо желанию (ниже — JS)
JSXNo
Vue RouterYes
PiniaNo
Vitest / CypressNo

После npm run dev откройте адрес из терминала (обычно 5173). Сохранили файл — страница обновилась (HMR).

Структура

src/App.vue — корень. src/components/ — ваши блоки UI. src/main.js монтирует приложение в #app.


Файл .vue — три блока

<script setup> ← логика
<template> ← разметка + директивы
<style scoped> ← стили только этого компонента

Разбор:

  • <script setup> хранит реактивное состояние, функции и импорты компонента.
  • <template> описывает структуру интерфейса и связывает её с данными через интерполяцию и директивы.
  • <style scoped> ограничивает CSS текущим компонентом, чтобы стили не протекали в соседние части приложения.
  • Такое разделение делает файл .vue самодостаточным: логика, разметка и стиль живут рядом и проще поддерживаются.

Composition API и <script setup>

Полный src/App.vue:

Код ITЗагрузка примера кода…


Разбор — скрипт

КодСмысл
ref(0)Реактивная ячейка; в script меняем через .value
\&#123;\&#123; count \&#125;\&#125; в templateVue разворачивает ref сам
() => count.value++Обработчик клика — функция, не вызов сразу

Разбор — шаблон

СинтаксисРоль
\&#123;\&#123; name \&#125;\&#125;Подстановка текста
v-model="name"Двусторонняя связь с input
v-if="name"Показать блок, если имя не пустое
@click="increment"Событие клика (v-on:click)
.value

В <script setup> пишут count.value++. В шаблоне — просто {'{{ count }}'}.


computed

Производное значение без ручной синхронизации:

<script setup>

import { ref, computed } from 'vue'

const count = ref(0)
const doubled = computed(() => count.value * 2)
</script>

<template>
<p>Счётчик: {{ count }}, удвоенный: {{ doubled }}</p>
</template>

Разбор:

  • computed(() => count.value * 2) создаёт производное состояние, которое кешируется и пересчитывается только при изменении count.
  • В шаблоне &#123;&#123; doubled &#125;&#125; используется как обычная переменная, хотя в скрипте это вычисляемый ref.
  • Подход избавляет от ручной синхронизации между count и его производными значениями.
  • Шаблон остаётся декларативным: он только отображает состояние, а формулы находятся в script.

computed пересчитывается только когда меняются зависимости.


onMounted и заметки с API

  1. API "Заметки" на порту 3000.
  2. CORS или прокси — 263, 264.

Код ITЗагрузка примера кода…

Разбор:

  • onMounted(async () => { ... }) запускает асинхронный код после монтирования компонента и готовности UI.
  • fetch('http://127.0.0.1:3000/notes') запрашивает данные API; res.ok проверяет успешность HTTP-ответа.
  • notes.value = await res.json() сохраняет полученный массив в реактивное состояние для отрисовки списка.
  • Блок try/catch/finally разделяет успешный сценарий, ошибку и финальное выключение loading.
  • В шаблоне v-if / v-else-if / v-else управляет тремя состояниями интерфейса — загрузка, ошибка, данные.
ЭлементЗачем
onMountedКод после появления компонента на странице
v-for + :keyСписок со стабильными id
v-if / v-else-ifСостояния загрузки и ошибки

Дочерний компонент

src/components/Counter.vue:

<script setup>
defineProps({ value: { type: Number, required: true } })
const emit = defineEmits(['increment', 'decrement', 'reset'])
</script>

<template>
<section class="counter">
<h2>Счётчик: {{ value }}</h2>
<button type="button" @click="emit('decrement')">−</button>
<button type="button" @click="emit('reset')">Сброс</button>
<button type="button" @click="emit('increment')">+</button>
</section>
</template>

Разбор:

  • defineProps(...) объявляет входные данные компонента и валидирует обязательность value.
  • defineEmits(['increment', 'decrement', 'reset']) фиксирует контракт событий, которые компонент отправляет родителю.
  • emit('...') в обработчике кнопки передаёт намерение действия наверх, не меняя состояние напрямую.
  • Компонент остаётся переиспользуемым: он отображает значение и генерирует события, а бизнес-логика хранится у родителя.

App.vue:

Код ITЗагрузка примера кода…

Разбор:

  • import Counter from './components/Counter.vue' подключает дочерний компонент в родительский App.vue.
  • :value="count" передаёт реактивное значение вниз через props.
  • @increment, @decrement, @reset подписывают родитель на события ребёнка и изменяют count в одном источнике истины.
  • Паттерн формирует предсказуемую архитектуру: данные вниз, события вверх.

Props вниз, события вверх — как в React.


Options API — устаревший стиль

Код ITЗагрузка примера кода…

Разбор:

  • data() возвращает начальное состояние компонента в стиле Options API.
  • В methods размещаются обработчики, которые вызываются из шаблона через @click.
  • this.count++ и this.count-- меняют реактивное поле экземпляра компонента.
  • Пример иллюстрирует legacy-стиль Vue 2/раннего Vue 3, который часто встречается в существующих кодовых базах.
Options APIComposition API
data()ref() / reactive()
this.count++count.value++
Учебные и старые кодовые базыНовые проекты, composables

Стили scoped

<style scoped> ограничивает CSS этим компонентом. Цвет #42b883 — фирменный зелёный Vue.


Краткий обзор концепций Vue

Реактивность связывает данные и DOM. Шаблон описывает, что показать. Директивы v-* добавляют поведение. Компоненты делят UI на части.


Практика — что добавить самому

  • Кнопка ×2: count.value *= 2.
  • Todo на ref([]) и v-for.
  • Таймер: setInterval в onMounted, clearInterval в onUnmounted.
  • POST заметки: fetch с method: 'POST' и JSON.stringify — шаблоны с разбором в Fetch / axios — типовые запросы.

Запуск

  1. Node.js LTS.
  2. Установка и dev-сервер (npm create vue@latestnpm installnpm run dev):
npm create vue@latest
npm install
npm run dev

Разбор:

  • Первая команда создаёт новый проект Vue через официальный генератор.
  • Вторая устанавливает зависимости, необходимые для сборки и запуска.
  • Третья поднимает dev-сервер с наблюдением за файлами.
  • Три команды покрывают базовую инициализацию проекта с нуля.
  1. Вставить код в App.vue.
  2. (Опционально) второй терминал — API 262.
  3. Production: npm run build → каталог dist/.
npm run build

Разбор:

  • Команда запускает production-сборку и генерирует оптимизированные файлы в dist/.
  • На этапе сборки выполняются минификация, разделение чанков и удаление неиспользуемого кода.
  • Результат готов к публикации на статический хостинг или интеграции в CI/CD-пайплайн.
  • Ошибки сборки на этом шаге обычно сигнализируют о проблемах импорта, типов или конфигурации.

Частые ошибки

СимптомПричина
Счётчик не двигаетсяНет .value в script
CORS264
Список без keyПредупреждения Vue при v-for

Что попробовать

  1. React 272 на том же API — галерея компонентов для сравнения синтаксиса.
  2. Vue Router — страница /about.
  3. Next 2731 для SSR.

Связанные материалы

ТемаМатериал
ОбзорVue.js
Галерея примеровVue и Svelte — лаборатория
FullstackFullstack на JavaScript — API и фронтенд
Чек-листJavaScript — чек-лист

Vue удобен тем, что первая программа похожа на вёрстку, а дальше тот же проект растёт до SPA с API и тестами.


Основа по протоколу

Базовый разбор HTTP и HTTPS находится в отдельной статье — HTTP как основа веб-интеграций.


В подборках

Статья входит в тематические подборки и блок "С чего начать?" на главной. Соседние шаги того же маршрута:

Первые шаги (маршрут подборки) — Первая программа на React, Первая программа на Angular, Первая программа на visual-basic, Первая программа на Ext JS, Первая программа на Pascal, Первая программа на Next.js.