Олег Марков
Организация файлов и структура проекта Vue.js
Введение
Когда вы начинаете работать с Vue.js, очень важно с самого начала правильно организовать структуру проекта и его файлов. От этого зависит, насколько понятно и удобно будет поддерживать ваш код, как быстро новые разработчики смогут разобраться в вашем проекте, и насколько легко ваш проект будет масштабироваться по мере роста.
В этой статье вы узнаете, какая структура папок и файлов считается хорошей практикой в экосистеме Vue.js, как и куда размещать компоненты, конфигурационные файлы, страницы, стили и прочие ресурсы. Здесь вы встретите конкретные рекомендации и практические примеры, которые помогут вам выстроить проект так, чтобы никакая хаотичная папка или запутанный импорт больше не мешали вашей работе.
Хотите разобраться глубже? Пройдите Освоить Vue 3 и Pinia на курсе — практика, наставники, реальные проекты.
Курс по теме
Освоить Vue 3 и Pinia на курсе
40 000+ студентов · рейтинг 4.8 · гарантия возврата 30 дней
Что такое структура проектов во Vue.js
Краткое общее описание
Структура проекта — это способ организации всех файлов и папок, которые входят в состав вашего приложения. Во Vue.js структура отражает не только технические аспекты (например, где хранить компоненты), но и проектные решения, такие как разделение логики, стилизации, хранилища данных (store) и точек входа.
Если вы когда-либо создавали проект через Vue CLI, системы сборки типа Vite, или вручную — вы наверняка видели схожие шаблоны директорий. Вот пример базовой структуры, которую создает Vue CLI:
my-vue-project/
├─ node_modules/
├─ public/
│ └─ index.html
├─ src/
│ ├─ assets/
│ ├─ components/
│ ├─ App.vue
│ ├─ main.js
├─ .gitignore
├─ package.json
├─ README.md
Смотрите, такая структура уже содержит разные уровни вложенности и четкое разделение по назначению. Давайте рассмотрим каждую часть подробнее.
Корневые директории и их назначение
Папка public
Это место для статичных ресурсов, которые не будут проходить через систему сборки Webpack или Vite. Сюда относят файлы, которые как есть попадут в итоговую сборку: favicon иконки, robots.txt, index.html.
Пример:
public/favicon.ico— иконка сайта в браузере.public/index.html— главный HTML-файл с точкой монтирования приложения.
Почему это важно? Любое содержимое внутри public скопируется на сервер как есть, без изменений.
Правильная организация файлов и структуры проекта — залог успешной разработки и поддержки Vue-приложения. Но для создания по-настоящему сложных и масштабируемых проектов, важно также понимать принципы работы с компонентами, маршрутизацией и управлением состоянием. Если вы хотите получить комплексные знания и навыки в разработке Vue-приложений, приходите на наш большой курс Vue.js 3, Vue Router и Pinia. На курсе 173 уроков и 21 упражнение, AI-тренажеры для безлимитной практики с кодом и задачами 24/7, решение задач с живым ревью наставника, еженедельные встречи с менторами.
Папка src
Это главный "рабочий" каталог, где находится весь исходный код приложения: компоненты, стили, модули состояния, страницы и утилиты.
Основные подпапки:
assets/— изображения, шрифты, статические стили.components/— переиспользуемые элементы Vue-компонентов.views/илиpages/— компоненты-страницы, которые используются роутером.router/— конфигурация маршрутизации (например,index.jsс описанием путей).store/— управление состоянием приложения (Vuex, Pinia).App.vue— корневой компонент (шаблон обертки для всего приложения).main.jsилиmain.ts— точка входа в приложение.
Ниже вы увидите развернутую структуру, рекомендованную для проектов средней и высокой степени сложности.
Пример расширенной структуры Vue.js приложения
src/
├─ assets/
│ ├─ styles/
│ │ └─ main.scss
│ └─ images/
├─ components/
│ ├─ BaseButton.vue
│ └─ TheHeader.vue
├─ views/
│ ├─ HomeView.vue
│ └─ AboutView.vue
├─ router/
│ └─ index.js
├─ store/
│ └─ index.js
├─ utils/
│ └─ helpers.js
├─ App.vue
├─ main.js
Пояснения:
assets/styles/main.scss— глобальные стили.components/BaseButton.vue— базовый компонент для кнопок.utils/helpers.js— вспомогательные функции.
Организация компонентов
Почему стоит дробить компоненты
Vue.js построен вокруг компонентов: модульных, переиспользуемых блоков интерфейса. Разбивка компонентов помогает вам держать код читабельным, редко встречаться с конфликтами имен и ускоряет процесс переиспользования.
Категории компонентов
- Базовые (Base, App) — используют префиксы для обозначения (BaseButton, AppLogo).
- Макросоставные (TheSidebar, TheHeader) — определяют основные части макета сайта.
- Функциональные или логические — специфичны для одной задачи или домена (UserProfile, TaskCard).
Пример базового компонента
Вот так может выглядеть универсальная кнопка:
<!-- components/BaseButton.vue -->
<template>
<button :class="type" @click="$emit('click')">
<slot/>
</button>
</template>
<script>
export default {
name: 'BaseButton',
props: {
type: {
type: String,
default: 'primary' // Используется CSS класс для стиля кнопки
}
}
}
</script>
<style scoped>
.primary { background: blue; color: #fff; }
.secondary { background: gray; color: #222; }
</style>
Теперь вы можете использовать <BaseButton> в разных местах, не дублируя логику и стили.
Группировка компонентов по доменам
В проектах посложнее иногда рекомендуют организовывать компоненты по фичам (feature-based structure):
src/
├─ features/
│ ├─ auth/
│ │ ├─ Login.vue
│ │ └─ Register.vue
│ └─ profile/
│ ├─ ProfileEdit.vue
│ └─ AvatarUpload.vue
Такой подход облегчает поддержку и масштабирование, поскольку все компоненты одной сущности лежат в одном месте.
Организация страниц (Views или Pages)
Если вы используете vue-router, каждая страница должна быть отдельным компонентом чаще всего, крупным Vue-файлом. Для них обычно создают папку views или pages:
src/
├─ views/
│ ├─ HomeView.vue
│ ├─ AboutView.vue
│ └─ UserProfile.vue
Здесь страницы не подразумевают переиспользования (в отличие от компонентов). Это конечные пункты маршрутов.
Пример маршрутизации:
// router/index.js
import { createRouter, createWebHistory } from 'vue-router'
import HomeView from '../views/HomeView.vue'
import AboutView from '../views/AboutView.vue'
const routes = [
{ path: '/', name: 'Home', component: HomeView },
{ path: '/about', name: 'About', component: AboutView }
]
const router = createRouter({
history: createWebHistory(),
routes
})
export default router
Здесь каждый путь ведет к конкретному компоненту страницы.
Организация состояния (Store)
В современных проектах Vue.js чаще применяют либо Vuex, либо Pinia. Обычно состояние размещают в папке store или stores.
Пример структуры c Pinia:
src/
├─ stores/
│ └─ user.js
user.js:
import { defineStore } from 'pinia'
export const useUserStore = defineStore('user', {
state: () => ({
name: '',
isLoggedIn: false
}),
actions: {
login(name) {
this.name = name
this.isLoggedIn = true
},
logout() {
this.name = ''
this.isLoggedIn = false
}
}
})
Как видно, папка долна содержать отдельные модули для разных аспектов состояния, такие как user, products и так далее.
Организация стилей
Где хранить стили
Глобальные стили обычно держат в src/assets/styles/ или — для малых проектов — прямо в App.vue.
Используйте препроцессоры (Sass, Less) для структурирования больших файлов стилей, разделяйте их по смыслу: variables, mixins, base, layout и так далее.
Пример импортов стилей в главный файл:
// assets/styles/main.scss
@import 'variables';
@import 'mixins';
@import 'base';
@import 'layout';
В каждом компоненте стили можно хранить как scoped (действуют только в рамках этого компонента).
Организация утилит и вспомогательных функций
В папке utils часто хранят функции, которые используются сразу в нескольких местах приложения.
Пример:
// utils/date.js
export function formatDate(date) {
// Преобразует дату к виду ДД.ММ.ГГГГ
return new Date(date).toLocaleDateString('ru-RU')
}
Использование в компоненте:
import { formatDate } from '@/utils/date'
setup() {
return { formatted: formatDate('2024-04-19T14:30:00.000Z') }
}
Логическая группировка по областям приложения
Когда проект становится большим, структура по прямой специализации (assets, components, views) может уже не подходить. Решение — группировка по областям (feature or domain-based):
src/
├─ features/
│ ├─ cart/
│ │ ├─ CartView.vue
│ │ ├─ CartItem.vue
│ │ └─ cartStore.js
│ └─ product/
│ ├─ ProductList.vue
│ └─ productStore.js
Такой подход делает работу над каждой частью независимой, удобно делегировать задачи внутри команды. Вы можете объединять логику, компоненты и стор для каждой области отдельно.
Как организовать логику для тестов
Для модульных тестов создайте папку tests/unit/, для end-to-end — tests/e2e/. Обычно структура тестов повторяет структуру исходников.
tests/
├─ unit/
│ ├─ components/
│ ├─ views/
Тесты обычно именуют как ComponentName.spec.js.
Советы по масштабируемости
- Следите за размером папок: если в папке становится слишком много файлов одного типа — делите ее дальше или переименовывайте по смыслу.
- Разделяйте осмысленно: не бойтесь создавать новые уровни вложенности, если это облегчает навигацию.
- Используйте alias для путей (
@/components/ComponentName.vue), чтобы импорты не стали сложными при большом количестве уровней.
Поддержка TypeScript
Если используете Vue с TypeScript, структура аналогична, только файлы компонентов могут иметь расширение .vue, а логика — .ts или .d.ts.
Пример:
src/
├─ components/
│ └─ TypedButton.vue
├─ types/
│ └─ user.ts
Вынесите общие типы в src/types.
Заключение
Грамотная организация файлов и папок в проекте Vue.js играет ключевую роль в поддерживаемости и масштабируемости вашего приложения. На старте проекта важно выбрать стратегию структуры: классическое разделение компонентов или группировка по областям (features), и придерживаться выбранного подхода по мере роста. Такой подход поможет вашей команде экономить время, избегать дублирования кода и успешно развивать проект в долгосрочной перспективе.
Организация файлов — это важный, но не единственный аспект успешной разработки Vue-приложений. Чтобы создавать по-настоящему профессиональные решения, нужно уверенно владеть маршрутизацией, управлением состоянием и другими важными аспектами. На нашем курсе Vue.js 3, Vue Router и Pinia вы получите все необходимые знания и навыки. В первых 3 модулях уже доступно бесплатное содержание — начните погружаться в мир Vue прямо сегодня.
Частозадаваемые технические вопросы по теме и ответы на них
Как подключить глобальную библиотеку стилей (например, Bootstrap или Tailwind) в проект Vue.js?
Ответ:
Добавьте нужную библиотеку через npm (npm install bootstrap), после чего импортируйте CSS-файл нужной библиотеки в main.js или в главный файл стилей (assets/styles/main.scss). Например:
// main.js
import 'bootstrap/dist/css/bootstrap.min.css'
В случае c Tailwind — создайте файл стилей, например, src/assets/styles/tailwind.css, и импортируйте его в точке входа (main.js).
Как разделять сторы в Vuex или Pinia между областями бизнес-логики?
Ответ:
Создавайте по отдельному модулю стор для каждой области. Например, для пользователей — src/stores/user.js, для корзины — src/stores/cart.js. В Pinia каждый store — отдельная функция через defineStore, а в Vuex — отдельный модуль в modules/.
Как добавить alias для импортов (например, чтобы можно было использовать @/components/...)?
Ответ:
Для Vite отредактируйте vite.config.js, добавьте в resolve.alias:
import { fileURLToPath, URL } from 'node:url'
export default defineConfig({
resolve: {
alias: {
'@': fileURLToPath(new URL('./src', import.meta.url))
}
}
})
Для Vue CLI используйте настройку в vue.config.js (или используйте по умолчанию @, который уже нацелен на src).
Как организовать вложенные маршруты (Nested Routes) и компоненты для них?
Ответ:
В router/index.js для маршрута используйте свойство children, где указываете дочерние маршруты:
const routes = [
{
path: '/dashboard',
component: DashboardView,
children: [
{ path: 'stats', component: StatsView }
]
}
]
В компоненте DashboardView используйте <router-view/> для вывода дочерних компонентов.
Где хранить конфиденциальные данные и переменные окружения (например, API ключи)?
Ответ:
Создайте файл .env в корне и определите переменные с префиксом VUE_APP_ (или VITE_ для Vite):
VITE_API_KEY=your_api_key_here
Получайте из кода через import.meta.env.VITE_API_KEY (Vite) или process.env.VUE_APP_MY_KEY (Vue CLI). Не коммитьте реальные ключи в репозиторий!
Постройте личный план изучения Vue до уровня Middle — бесплатно!
Vue — часть карты развития Frontend
100+ шагов развития
30 бесплатных лекций
300 бонусных рублей на счет
Бесплатные лекции
Все гайды по Vue
Лучшие курсы по теме

Vue 3 и Pinia
Антон Ларичев
TypeScript с нуля
Антон Ларичев