Vue и Svelte — готовые компоненты
Приветствую! Здесь вы наверняка найдете, что ищете. Примеры в лаборатории рассчитаны на то, что мы разбираем что-то конкретное.
Текущая статья посвящена примерам: Vue 3 и Svelte 5 с построчным разбором.
Поэтому за теорией по текущей теме вам — в энциклопедию. Если ещё не погружались, то маршрут прост:
- Основы
- Система и сеть
- Данные и разметка
- Код и разработка
- Языки
- Искусственный интеллект
- Проект
- Инфраструктура и безопасность
- Спин-офф
Обязательно пройдитесь.
А теперь приступим к нашему предмету.
Пошаговый 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 минуты
- Установите Node.js LTS — в терминале
node -vиnpm -vпоказывают версии. - Выполните команды из Создание проекта.
- Откройте
src/App.vue(Vue) илиsrc/routes/+page.svelte(SvelteKit). - Удалите шаблонный код, вставьте пример целиком (включая
<style>, если он в блоке). npm run dev— откройте ссылку из терминала (частоhttp://localhost:5173).- Сохранили файл — страница обновилась (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 { createApp } 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 { ref } from 'vue' |
Импорт из пакета vue |
Разбор — template:
| Строка | Смысл |
|---|---|
{{ message }} |
Подстановка текста; без .value в шаблоне |
<style scoped> |
CSS только для этого компонента |
Что увидите: заголовок «Привет, Vue!» по центру.
Попробуйте: в script после объявления: message.value = 'Лабораторная №3'.
Обязательный каркас Svelte
Разбор построчно:
| Строка | Смысл |
|---|---|
$state('…') |
Реактивность Svelte 5 (runes) |
{message} |
Интерполяция — одни фигурные скобки, не двойные как во 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 = () => { count.value *= 2 } и @click="double".
Счётчик и поле имени — Svelte
Сравнение с Vue:
| Идея | Vue | Svelte |
|---|---|---|
| Состояние | ref(0) + .value |
$state(0) + count += 1 |
| Input | v-model="name" |
bind:value={name} |
| Условие | v-if="name" |
{#if name} … {/if} |
| Клик | @click="fn" |
onclick={fn} |
Список задач — 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="{ done: task.done }" |
Зачёркивание через CSS-класс |
filter в removeTask |
Новый массив без удалённой строки |
Список задач — Svelte
Разбор:
| Строка | Смысл |
|---|---|
tasks = [..tasks, item] |
Новая ссылка на массив — явное обновление |
{#each tasks as task (task.id)} |
Цикл; (task.id) — ключ, как :key во Vue |
class:done={task.done} |
Условный класс в 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 |
Три экрана: ждём, ошибка, данные |
Шаблоны fetch — Fetch / axios — типовые запросы.
Загрузка с API — Svelte
Разбор: onMount из svelte — аналог onMounted. {:else if} — цепочка условий.
Дочерний компонент — 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 |
Сырой {{ count }} на странице |
Нет 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 |
На старте достаточно 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/{#each}есть ключ. -
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 |