Прогресивний JavaScript фреймворк для створення сучасних веб-інтерфейсів!
📚 Урок 5 • Frontend • 25 хв читанняVue.js (вимовляється "вʼю", як англійське "view") — це прогресивний JavaScript фреймворк для створення користувацьких інтерфейсів. Його створив Evan You у 2014 році, і з того часу Vue став одним з найпопулярніших фреймворків у світі!
Vue — це як LEGO для веб-сторінок! Ти будуєш інтерфейс з маленьких компонентів, які можна перевикористовувати. Змінив дані — сторінка автоматично оновилась! Це називається реактивність ✨
Vue можна використовувати по-різному:
Якщо знаєш HTML, CSS, JS — почнеш писати на Vue за години, не дні!
Зміни в даних автоматично оновлюють DOM. Ніякого ручного маніпулювання!
Розбий інтерфейс на незалежні компоненти та перевикористовуй їх
~33KB gzipped — швидко завантажується, швидко працює
Vue DevTools для Chrome — дебаг компонентів та стану
Vue Router, Pinia, Nuxt.js — все що треба для великих проєктів
Офіційний сайт Nintendo
Деякі внутрішні інструменти
Повністю на Vue.js
Найбільший e-commerce Китаю
Є два способи почати працювати з Vue: через CDN (швидко) або через Vite (для серйозних проєктів).
Найшвидший спосіб спробувати Vue — просто підключити через CDN:
<!DOCTYPE html> <html lang="uk"> <head> <meta charset="UTF-8"> <title>Мій перший Vue додаток</title> <!-- Підключаємо Vue 3 через CDN --> <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script> </head> <body> <!-- Контейнер для Vue додатку --> <div id="app"> <h1>{{ message }}</h1> <button @click="count++">Клікнуто: {{ count }} разів</button> </div> <script> const { createApp, ref } = Vue createApp({ setup() { const message = ref('🦉 Привіт від Vue!') const count = ref(0) return { message, count } } }).mount('#app') </script> </body> </html>
Збережи цей файл як index.html і відкрий у браузері — ти побачиш свій перший Vue додаток! Натискай на кнопку — лічильник оновлюється автоматично!
Vite — це сучасний інструмент для створення Vue проєктів. Швидкий, з гарячим перезавантаженням!
# Створення нового Vue проєкту npm create vue@latest # Відповідай на питання: # Project name: my-vue-app # Add TypeScript? No (поки що) # Add JSX Support? No # Add Vue Router? Yes (для навігації) # Add Pinia? Yes (для стану) # Перейди в папку та запусти cd my-vue-app npm install npm run dev
Відкрий http://localhost:5173 — твій Vue проєкт працює! 🎉
my-vue-app/ ├── 📁 node_modules/ # Залежності ├── 📁 public/ # Статичні файли ├── 📁 src/ # Вихідний код │ ├── 📁 assets/ # Картинки, шрифти │ ├── 📁 components/ # Vue компоненти │ ├── 📁 views/ # Сторінки │ ├── 📁 router/ # Налаштування роутінгу │ ├── 📁 stores/ # Pinia стори │ ├── 📄 App.vue # Головний компонент │ └── 📄 main.js # Точка входу ├── 📄 index.html # HTML шаблон ├── 📄 package.json # Залежності проєкту └── 📄 vite.config.js # Конфігурація Vite
Давай розберемо ключові концепції Vue!
Подвійні фігурні дужки {{ }} виводять дані в HTML:
<template> <!-- Виведення тексту --> <p>Привіт, {{ name }}!</p> <!-- Вирази JavaScript --> <p>2 + 2 = {{ 2 + 2 }}</p> <p>{{ message.toUpperCase() }}</p> <p>{{ isAdmin ? 'Адмін' : 'Користувач' }}</p> </template> <script setup> const name = 'Кудик' const message = 'привіт' const isAdmin = true </script>
Щоб дані автоматично оновлювали інтерфейс, використовуй ref() або reactive():
<template> <div> <h2>Лічильник: {{ count }}</h2> <button @click="increment">+1</button> <button @click="decrement">-1</button> <button @click="reset">Скинути</button> <p>Подвоєне: {{ doubled }}</p> </div> </template> <script setup> import { ref, computed } from 'vue' // ref() для примітивів (числа, рядки, boolean) const count = ref(0) // Методи const increment = () => count.value++ const decrement = () => count.value-- const reset = () => count.value = 0 // Computed — автоматично перераховується const doubled = computed(() => count.value * 2) </script>
ref() — для примітивів (число, рядок), доступ через .value. reactive() — для обʼєктів, без .value. У template обидва працюють без .value!
Директиви — це спеціальні атрибути з префіксом v-:
Звʼязує атрибут з даними::href="url":class="className"
Обробка подій:@click="handler"@submit="save"
Двостороннє звʼязування:v-model="name"
Для форм!
Умовний рендеринг:v-if="isVisible"v-else
Показати/сховати:v-show="isOpen"
CSS display: none
Цикл по масиву:v-for="item in items"
Потрібен :key!
<template> <div class="todo-app"> <h1>📝 Мої справи</h1> <!-- v-model для двостороннього звʼязування --> <input v-model="newTodo" @keyup.enter="addTodo" placeholder="Нова справа..." /> <button @click="addTodo">Додати</button> <!-- v-if для умовного рендерингу --> <p v-if="todos.length === 0">Список порожній 🎉</p> <!-- v-for для списку --> <ul v-else> <li v-for="(todo, index) in todos" :key="index"> <!-- :class для динамічних класів --> <span :class="{ done: todo.done }" @click="todo.done = !todo.done"> {{ todo.text }} </span> <button @click="removeTodo(index)">❌</button> </li> </ul> </div> </template> <script setup> import { ref } from 'vue' const newTodo = ref('') const todos = ref([ { text: 'Вивчити Vue', done: false }, { text: 'Створити проєкт', done: false } ]) const addTodo = () => { if (newTodo.value.trim()) { todos.value.push({ text: newTodo.value, done: false }) newTodo.value = '' } } const removeTodo = (index) => todos.value.splice(index, 1) </script>
Компоненти — це будівельні блоки Vue додатку. Кожен компонент — окремий файл .vue з власним HTML, CSS та JS!
<!-- 1️⃣ TEMPLATE — HTML розмітка --> <template> <div class="my-component"> <h2>{{ title }}</h2> <p>{{ description }}</p> </div> </template> <!-- 2️⃣ SCRIPT — JavaScript логіка --> <script setup> const title = 'Мій компонент' const description = 'Це Vue компонент!' </script> <!-- 3️⃣ STYLE — CSS стилі (scoped = тільки для цього компонента) --> <style scoped> .my-component { padding: 20px; background: #f0f0f0; border-radius: 10px; } </style>
<template> <div class="user-card"> <img :src="avatar" :alt="name"/> <h3>{{ name }}</h3> <p>{{ role }}</p> </div> </template> <script setup> // Оголошення props const props = defineProps({ name: { type: String, required: true }, role: { type: String, default: 'Користувач' }, avatar: { type: String, default: '/default-avatar.png' } }) </script>
<template> <div> <h1>Наша команда</h1> <!-- Використання компонента --> <UserCard name="Кудик" role="Маскот Koodi" avatar="/kudik.png" /> <!-- Можна передавати динамічні дані --> <UserCard v-for="user in users" :key="user.id" :name="user.name" :role="user.role" /> </div> </template> <script setup> import UserCard from './components/UserCard.vue' </script>
<!-- Button.vue --> <template> <button @click="handleClick">{{ label }}</button> </template> <script setup> const props = defineProps(['label']) const emit = defineEmits(['clicked']) const handleClick = () => { emit('clicked', 'Привіт від кнопки!') } </script> <!-- Використання: --> <!-- <Button label="Натисни" @clicked="onButtonClick" /> -->
Vue Router — офіційний роутер для Vue.js. Дозволяє створювати односторінкові додатки (SPA) з навігацією між "сторінками".
npm install vue-router@4import { createRouter, createWebHistory } from 'vue-router' // Імпортуємо сторінки import Home from '../views/Home.vue' import About from '../views/About.vue' import Contact from '../views/Contact.vue' // Визначаємо маршрути const routes = [ { path: '/', name: 'home', component: Home }, { path: '/about', name: 'about', component: About }, { path: '/contact', name: 'contact', component: Contact } ] const router = createRouter({ history: createWebHistory(), routes }) export default router
<template> <nav> <!-- router-link замість <a> --> <router-link to="/">🏠 Головна</router-link> <router-link to="/about">ℹ️ Про нас</router-link> <router-link to="/contact">📧 Контакти</router-link> </nav> <main> <!-- Тут рендериться поточна сторінка --> <router-view /> </main> </template>
<router-link> — створює посилання без перезавантаження сторінки. <router-view> — місце, куди буде вставлятися компонент поточного маршруту!
Pinia — офіційна бібліотека для управління станом у Vue. Замінила Vuex, простіша та зручніша!
npm install piniaimport { defineStore } from 'pinia' import { ref, computed } from 'vue' export const useCounterStore = defineStore('counter', () => { // State — реактивні дані const count = ref(0) const name = ref('Koodi') // Getters — computed властивості const doubleCount = computed(() => count.value * 2) // Actions — методи function increment() { count.value++ } function reset() { count.value = 0 } return { count, name, doubleCount, increment, reset } })
<template> <div> <p>Count: {{ counter.count }}</p> <p>Double: {{ counter.doubleCount }}</p> <button @click="counter.increment()">+1</button> <button @click="counter.reset()">Reset</button> </div> </template> <script setup> import { useCounterStore } from '@/stores/counter' // Отримуємо доступ до store const counter = useCounterStore() </script>
Офіційне розширення! Підсвітка, IntelliSense, перевірка типів. Must-have!
Сніпети для швидкого написання Vue коду. vbase, vfor, vmodel
Перевірка коду на помилки та стиль. Працює з eslint-plugin-vue
Автоформатування коду. Ідеально працює з Vue файлами
Встанови Vue DevTools для браузера (Chrome/Firefox) — дебаг компонентів, стану Pinia, роутів!
onMounted, onUpdated, onUnmounted — життєвий цикл компонента
watch, watchEffect — відстеження змін у даних
Передача контенту в компоненти. default та named slots
Повторне використання логіки. Свої хуки!
Meta-фреймворк для Vue. SSR, SSG, file-based routing
Типізація для надійнішого коду. Vue 3 + TS = 💪