Vue.js строится вокруг системы реактивности, в которой состояние приложения автоматически связывается с DOM. Изменение данных приводит к автоматическому обновлению представления без ручного вмешательства в DOM-операции.
Реактивность в Vue основана на проксировании объектов состояния. В
современных версиях (Vue 3) используется Proxy, позволяющий
отслеживать чтение и запись свойств объекта:
import { reactive } from 'vue'
const state = reactive({
count: 0
})
state.count++
Каждое изменение state.count фиксируется системой и
триггерит обновление всех зависимостей, которые используют это
значение.
Ключевое свойство реактивной модели — автоматическое отслеживание зависимостей. Компонент не подписывается вручную на изменения; Vue определяет зависимости во время выполнения функции рендера.
Vue.js организует приложение как дерево компонентов. Каждый компонент инкапсулирует логику, шаблон и стили.
Базовая структура компонента:
export default {
name: 'CounterComponent',
data() {
return {
count: 0
}
},
methods: {
increment() {
this.count++
}
}
}
Компонент разделяет три ключевых слоя:
В современном Vue предпочтение отдаётся Composition API, где логика группируется по функциональному признаку, а не по опциям объекта.
Composition API вводит функцию setup, в которой
формируется реактивное состояние и поведение компонента.
import { ref } from 'vue'
export default {
setup() {
const count = ref(0)
const increment = () => {
count.value++
}
return {
count,
increment
}
}
}
Использование ref и reactive позволяет
строить гибкие структуры состояния.
Основные преимущества подхода:
Vue предоставляет набор встроенных директив для декларативного управления DOM.
<img v-bind:src="imageUrl" />
Сокращённая форма:
<img :src="imageUrl" />
<input v-model="text" />
v-model связывает значение input с реактивным
состоянием.
<div v-if="isVisible">Контент</div>
<div v-show="isVisible">Контент</div>
Разница:
v-if добавляет/удаляет элементы из DOMv-show управляет CSS display<li v-for="item in items" :key="item.id">
{{ item.name }}
</li>
Ключ key обеспечивает стабильную идентификацию элементов
при обновлении списка.
Компоненты Vue проходят ряд фаз от создания до удаления. Эти фазы позволяют подключать побочные эффекты и управлять ресурсами.
Основные хуки жизненного цикла:
Пример использования:
import { onMounted, onUnmounted } from 'vue'
export default {
setup() {
onMounted(() => {
console.log('Компонент смонтирован')
})
onUnmounted(() => {
console.log('Компонент уничтожен')
})
}
}
Жизненный цикл критичен при работе с:
Computed properties позволяют создавать производные значения на основе реактивного состояния с автоматическим кэшированием.
import { ref, computed } from 'vue'
const price = ref(100)
const quantity = ref(2)
const total = computed(() => {
return price.value * quantity.value
})
Особенности:
Watchers используются для отслеживания изменений конкретных реактивных значений.
import { ref, watch } from 'vue'
const search = ref('')
watch(search, (newValue, oldValue) => {
console.log('Изменение:', oldValue, '→', newValue)
})
Watch применяется при необходимости:
При росте приложения локального состояния компонентов становится недостаточно. Используются централизованные хранилища, наиболее распространённое — Pinia.
import { defineStore } from 'pinia'
export const useCounterStore = defineStore('counter', {
state: () => ({
count: 0
}),
actions: {
increment() {
this.count++
}
}
})
Хранилище обеспечивает:
Vue Router отвечает за навигацию между страницами без перезагрузки.
import { createRouter, createWebHistory } from 'vue-router'
const routes = [
{ path: '/', component: Home },
{ path: '/about', component: About }
]
const router = createRouter({
history: createWebHistory(),
routes
})
Навигация реализуется через:
<router-link to="/about">О странице</router-link>
<router-view />
Router позволяет строить SPA-архитектуру с клиентским управлением маршрутами.
События в Vue обрабатываются через директиву v-on:
<button @click="handleClick">Нажать</button>
Передача данных между компонентами осуществляется через:
export default {
props: ['title'],
emits: ['update']
}
Такой подход обеспечивает однонаправленный поток данных.
Слоты позволяют передавать разметку в компонент извне.
<MyCard>
<h1>Заголовок</h1>
</MyCard>
Внутри компонента:
<template>
<div class="card">
<slot />
</div>
</template>
Слоты поддерживают:
Vue не ограничивает способ взаимодействия с сервером. Обычно
используется fetch или axios.
import { ref, onMounted } from 'vue'
const data = ref(null)
onMounted(async () => {
const response = await fetch('/api/items')
data.value = await response.json()
})
Асинхронные операции часто комбинируются с состояниями загрузки и ошибок:
const loading = ref(false)
const error = ref(null)
При увеличении сложности проекта структура начинает включать:
Composable-функции:
export function useCounter() {
const count = ref(0)
const increment = () => count.value++
return { count, increment }
}
Такой подход снижает связанность компонентов и повышает повторное использование логики.