Vue и Svelte — готовые компоненты

Приветствую! Здесь вы наверняка найдете, что ищете. Примеры в лаборатории рассчитаны на то, что мы разбираем что-то конкретное.

Текущая статья посвящена примерам: Vue 3 и Svelte 5 с построчным разбором.

Поэтому за теорией по текущей теме вам — в энциклопедию. Если ещё не погружались, то маршрут прост:

  1. Основы
  2. Система и сеть
  3. Данные и разметка
  4. Код и разработка
  5. Языки
  6. Искусственный интеллект
  7. Проект
  8. Инфраструктура и безопасность
  9. Спин-офф

Обязательно пройдитесь.

А теперь приступим к нашему предмету.

Теория и соседние материалы

Пошаговый tutorial Vue — первая программа на Vue.js.

Обзор фреймворка — Vue.js.

React для сравнения — первая программа на React и готовые React-компоненты.

Мобильный UI на Dart — Flutter и готовые виджеты.

Запросы к серверу — fetch / axios и Fullstack.

Каркас страницы — HTML + CSS.

После сборки — Nginx под SPA.


Основы Vue и Svelte в браузере


Навигация по примерам

Ищут в интернете Раздел ниже
vue 3 counter example ref Счётчик и имя — Vue
svelte 5 counter button onclick Счётчик и имя — Svelte
vue todo list v-for example Список задач — Vue
svelte each block todo Список задач — Svelte
vue fetch onmounted api Загрузка с API — Vue
svelte onmount fetch json Загрузка с API — Svelte
vue defineprops defineemits child Дочерний компонент — Vue
svelte component props callback Дочерний компонент — Svelte
npm create vue latest vite Создание проекта
vue mustache not working raw {{ }} Частые ошибки

Базовые термины

Термин Простыми словами
SPA Одна HTML-страница; при кликах контент меняет JavaScript, без полной перезагрузки
Компонент Файл с разметкой + логикой + стилями (как отдельный «виджет»)
Реактивность Изменили переменную в коде — экран обновился сам
ref (Vue) Реактивная «коробка»; в script меняют через .value
$state (Svelte 5) Реактивная переменная; присвоение count = 5 обновляет UI
v-model (Vue) Связь поля ввода и переменной в обе стороны
bind:value (Svelte) То же, что v-model для input
Vite Dev-сервер и сборка; при сохранении файла страница обновляется (HMR)
mount('#app') «Включить» Vue/Svelte в <div id="app"> на странице

Зачем фреймворк, если есть DOM

На чистом DOM вы пишете так:

const btn = document.getElementById('plus');
const span = document.getElementById('count');
let n = 0;
btn.addEventListener('click', () => {
  n += 1;
  span.textContent = String(n);
});

Смысл: число n живёт в JavaScript, а textContent — ваша обязанность вручную синхронизировать экран. В списке из 20 полей таких строк становится десятки. Подробнее приёмы без фреймворка — 30 приёмов DOM.

Во Vue и Svelte вы описываете что показать, а фреймворк обновляет DOM при смене данных.

flowchart LR
  A[Клик по кнопке] --> B[Меняется переменная]
  B --> C[Фреймворк сравнивает старое и новое]
  C --> D[Обновляются только нужные узлы DOM]

Как запустить пример за 2 минуты

  1. Установите Node.js LTS — в терминале node -v и npm -v показывают версии.
  2. Выполните команды из Создание проекта.
  3. Откройте src/App.vue (Vue) или src/routes/+page.svelte (SvelteKit).
  4. Удалите шаблонный код, вставьте пример целиком (включая <style>, если он в блоке).
  5. npm run dev — откройте ссылку из терминала (часто http://localhost:5173).
  6. Сохранили файл — страница обновилась (HMR).
Где Плюсы
Локально + Vite Как на работе: HMR, сборка dist/
StackBlitz Без установки Node
Vue SFC Playground Только .vue в браузере

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

Vue 3 + Vite

Задача: получить пустой проект с горячей перезагрузкой.

node -v
npm -v
npm create vue@latest my-vue-lab
cd my-vue-lab
npm install
npm run dev

Разбор команд:

Команда Смысл
node -v Проверка, что Node установлен
npm create vue@latest my-vue-lab Официальный генератор Vue 3 + Vite
cd my-vue-lab Все следующие команды — из папки проекта
npm install Скачать зависимости в node_modules/
npm run dev Dev-сервер; URL в терминале
Вопрос мастера На лабораторную
TypeScript можно No
Vue Router Yes, если нужны две «страницы»
Pinia No на старте

Svelte 5 + SvelteKit

npm create svelte@latest my-svelte-lab
cd my-svelte-lab
npm install
npm run dev

Разбор: генератор создаёт SvelteKit; главный UI обычно в src/routes/+page.svelte.

Production: npm run build → папка dist/ или .svelte-kit/output (зависит от шаблона). Статика на хостинг — Nginx SPA.


Обязательный каркас Vue

Задача: понять три блока .vue и точку входа main.js.

src/main.js


import { createApp } from 'vue'
import App from './App.vue'

createApp(App).mount('#app')

Разбор построчно:

Строка Смысл
import &#123; createApp &#125; from 'vue' Фабрика приложения Vue
import App from './App.vue' Корневой компонент — ваш экран
createApp(App) Связать приложение с компонентом
.mount('#app') Отрисовать внутри <div id="app"> из index.html

Минимальный src/App.vue

Разбор — script:

Строка Смысл
<script setup> Composition API: переменные видны в template
ref('…') Реактивная строка; в script — message.value
import &#123; ref &#125; from 'vue' Импорт из пакета vue

Разбор — template:

Строка Смысл
&#123;&#123; message &#125;&#125; Подстановка текста; без .value в шаблоне
<style scoped> CSS только для этого компонента

Что увидите: заголовок «Привет, Vue!» по центру.

Попробуйте: в script после объявления: message.value = 'Лабораторная №3'.


Обязательный каркас Svelte

Разбор построчно:

Строка Смысл
$state('…') Реактивность Svelte 5 (runes)
&#123;message&#125; Интерполяция — одни фигурные скобки, не двойные как во Vue
<style> Стили локальны для файла по умолчанию

Стартовые интерфейсы

Три задачи, которые чаще всего ищут: счётчик, список задач, загрузка JSON.


Счётчик и поле имени — Vue

Задача: vue 3 counter ref example, vue v-model input greeting

Задача: кнопки ±1, сброс, приветствие по имени.

Вставьте в src/App.vue:

Разбор — script:

Строка Смысл
ref(0) Реактивное число, старт 0
count.value++ В script у ref обязателен .value — главная ошибка новичков
() => { … } Функция передаётся в @click, не вызывается сразу

Разбор — template:

Синтаксис Смысл
v-model="name" Двусторонняя связь с input
v-if="name" Показать <h2>, только если строка не пустая
@click="increment" Сокращение v-on:click
type="button" Кнопка не отправляет форму

Что увидите: поле имени, приветствие при вводе, три кнопки счётчика.

Попробуйте: кнопка ×2 — const double = () => &#123; count.value *= 2 &#125; и @click="double".


Счётчик и поле имени — Svelte

Сравнение с Vue:

Идея Vue Svelte
Состояние ref(0) + .value $state(0) + count += 1
Input v-model="name" bind:value=&#123;name&#125;
Условие v-if="name" &#123;#if name&#125; … &#123;/if&#125;
Клик @click="fn" onclick=&#123;fn&#125;

Список задач — Vue

Задача: vue todo list v-for v-model

Разбор построчно:

Строка Смысл
tasks = ref([..]) Массив объектов в реактивной обёртке
trim() + if (!text) return Пустые задачи не добавляем
@submit.prevent Enter в поле добавляет задачу без перезагрузки страницы
v-for + :key="task.id" Список; ключ нужен для корректного обновления DOM
v-model="task.done" Чекбокс меняет поле объекта в массиве
:class="&#123; done: task.done &#125;" Зачёркивание через CSS-класс
filter в removeTask Новый массив без удалённой строки

Список задач — Svelte

Разбор:

Строка Смысл
tasks = [..tasks, item] Новая ссылка на массив — явное обновление
&#123;#each tasks as task (task.id)&#125; Цикл; (task.id) — ключ, как :key во Vue
class:done=&#123;task.done&#125; Условный класс в Svelte

Загрузка с API — Vue

Задача: vue 3 fetch onmounted example

Задача: при открытии страницы запросить JSON и показать список или ошибку.

Для теста без своего сервера — публичный API. Для курсовой с Node — API «Заметки» и Fullstack 264.

Разбор построчно:

Строка Смысл
onMounted Код после появления компонента в DOM
await fetch GET по умолчанию
!res.ok 404/500 — fetch не бросает ошибку сам
notes.value = await res.json() Массив в реактивное состояние
finally Снять «Загрузка…» всегда
v-if / v-else-if / v-else Три экрана: ждём, ошибка, данные

Шаблоны fetchFetch / axios — типовые запросы.


Загрузка с API — Svelte

Разбор: onMount из svelte — аналог onMounted. &#123;:else if&#125; — цепочка условий.


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

Задача: vue defineprops defineemits example

Задача: вынести счётчик в файл; родитель хранит число, ребёнок шлёт события.

src/components/Counter.vue:

Разбор:

Место Смысл
defineProps Данные вниз от родителя
defineEmits События вверх
:value="count" Привязка prop (v-bind:value)
@increment="count++" Родитель — единственный источник истины

Тот же паттерн в React — React — компоненты-рецепты.


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

src/lib/Counter.svelte:

<script>
  let { value = 0, onincrement, ondecrement, onreset } = $props()
</script>

<section class="counter">
  <h2>Счётчик: {value}</h2>
  <button type="button" onclick={ondecrement}>−</button>
  <button type="button" onclick={onreset}>Сброс</button>
  <button type="button" onclick={onincrement}>+</button>
</section>

Родитель:

<script>
  import Counter from './lib/Counter.svelte'
  let count = $state(0)
</script>

<Counter
  value={count}
  onincrement={() => count++}
  ondecrement={() => count--}
  onreset={() => { count = 0 }}
/>

Разбор: в Svelte 5 колбэки onincrement вместо emit из Svelte 4.


Форма с проверкой — Vue

Разбор:

Строка Смысл
submitted Ошибку показываем только после первой отправки
computed Пересчёт при смене email или submitted
emailError.value в onSubmit У computed в script тоже .value

Vue и Svelte — что выбрать на курсовой

Критерий Vue 3 Svelte 5
Синтаксис HTML + v-* HTML + {#…}
После HTML/CSS Обычно привычнее Мягкий вход
Вакансии Много Меньше, растёт
Учебник 282 экосистема JS

Один фреймворк на проект до рабочего pet-приложения — достаточно для зачёта.


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

Симптом Причина Решение
Счётчик не меняется (Vue) count++ без .value count.value++ в script
Сырой &#123;&#123; count &#125;&#125; на странице Нет mount('#app') Проверить main.js, консоль F12
Failed to fetch CORS или API выключен Fullstack на JavaScript — API и фронтенд, прокси Vite
Предупреждение про key Нет :key в v-for task.id
Svelte: список «застыл» Мутация без новой ссылки tasks = [..tasks, x]
404 на /about после build SPA без fallback Nginx SPA
Один UI-стек в репозитории

На старте достаточно Vue или Svelte (или React — отдельная статья).

Три фреймворка в одной папке ломают сборку.

Сравнение синтаксиса — здесь; курсовой проект — в одном выбранном стеке.


Практика — что добавить для зачёта

Усложнение Vue Svelte
Фильтр задач computed $derived
Таймер onMounted + onUnmounted onMount + cleanup
POST на API fetch + method: 'POST' то же
Две страницы Vue Router SvelteKit routes

Чек-лист перед сдачей лабораторной

  • npm run dev без ошибок, UI виден в браузере.
  • В Vue в script у ref при изменении есть .value.
  • У v-for / &#123;#each&#125; есть ключ.
  • fetch проверяет res.ok.
  • npm run build проходит успешно.

Куда двигаться дальше

Задача Материал
Tutorial Vue 282
React-рецепты React — компоненты-рецепты
DOM без фреймворка JavaScript DOM — 30 приёмов
fetch, axios Fetch / axios — типовые запросы
Turtle / p5 Примеры фигур Turtle на Python · Примеры фигур на Processing/p5.js