Организация файлов и структура проекта Vue.js

21 июля 2026
Автор

Олег Марков

Введение

Когда вы начинаете работать с Vue.js, очень важно с самого начала правильно организовать структуру проекта и его файлов. От этого зависит, насколько понятно и удобно будет поддерживать ваш код, как быстро новые разработчики смогут разобраться в вашем проекте, и насколько легко ваш проект будет масштабироваться по мере роста.

В этой статье вы узнаете, какая структура папок и файлов считается хорошей практикой в экосистеме Vue.js, как и куда размещать компоненты, конфигурационные файлы, страницы, стили и прочие ресурсы. Здесь вы встретите конкретные рекомендации и практические примеры, которые помогут вам выстроить проект так, чтобы никакая хаотичная папка или запутанный импорт больше не мешали вашей работе.

Курс по теме

Освоить 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Компоненты Vue создание передача данных события и emitСтрелочка вправо

Постройте личный план изучения Vue до уровня Middle — бесплатно!

Vue — часть карты развития Frontend

  • step100+ шагов развития
  • lessons30 бесплатных лекций
  • lessons300 бонусных рублей на счет

Бесплатные лекции

Все гайды по Vue

Руководство по валидации форм во Vue.jsИнтеграция Tiptap для создания редакторов на VueРабота с таблицами во Vue через TanStackИнструкция по установке и компонентам Vue sliderУправление пакетами Vue js с помощью npmУправление пакетами и node modules в Vue проектахКак использовать meta для улучшения SEO на VueПолный гайд по компоненту messages во Vuejs5 правил использования Inertia с Vue и LaravelРабота с модулями и пакетами в VueИнструкция по работе с grid на VueGithub для Vue проектов - подробная инструкция по хранению и совместной работеНастройка ESLint для Vue проектов и поддержка качества кодаОбработка ошибок и отладка в Vue.jsИспользование Vue Devtools для отладки и мониторинга приложенийРабота с конфигурационными файлами и скриптами VueСоздание и настройка проектов Vue с помощью Vue CLI3 способа интеграции Chart.js с Vue для создания графиковРабота с Canvas во VueИнструкция по реализации календаря во VueРабота с Ant Design Vue для создания UI на Vue
Vuex - полное руководство по управлению состоянием во Vue приложенияхРеактивные ссылки ref - полный разбор для разработчиковРеактивные объекты reactive-objects - подробное руководство с примерамиРеактивные переменные - концепция reactive и практические примерыМеханизм Provide Inject - как он работает и когда применятьPinia современный менеджер состояния для VueЛокальное состояние local state в веб разработкеГлобальное состояние в приложениях - global state
Обзор и использование утилит Vue для удобной разработкиРабота с обновлениями компонента и жизненным циклом updateРазрешение конфликтов и ошибок с помощью Vue resolveИспользование query-параметров и их обработка в маршрутах VueЗагрузка и управление состоянием загрузки в VueИспользование библиотек Vue для расширения функционалаРабота с JSON данными в приложениях VueКак работать с экземплярами компонента Instance во VueПолучение данных и API-запросы во Vue.jsЭкспорт и импорт данных и компонентов в VueОбработка событий и их передача между компонентами VuejsГайд по defineEmits на Vue 3Понимание core функционала Vue и его применениеПонимание и применение Composition API в Vue 3Понимание и работа с компилятором VueКогда и как использовать $emit и call во VueВзаимодействие с внешними API через Axios в Vue
Веб приложения на Vue архитектура и лучшие практикиИспользование Vite для быстрого старта и сборки проектов на Vue 3Работа с URL и ссылками в приложениях на VueРабота с пользовательскими интерфейсами и UI библиотеками во VueОрганизация и структура исходных файлов в проектах VueИспользование Quasar Framework для разработки на Vue с готовыми UI-компонентамиОбзор популярных шаблонов и стартовых проектов на VueИнтеграция Vue с PHP для создания динамичных веб-приложенийКак организовать страницы и маршруты в проекте на VueNuxt JS и Vue 3 для SSR приложенийСоздание серверных приложений на Vue с помощью Nuxt jsИспользование Vue Native для разработки мобильных приложенийОрганизация и управление индексной страницей в проектах VueИспользование Docker для контейнеризации приложений на VueИнтеграция Vue.js с Django для создания полноценных веб-приложенийСоздание и работа с дистрибутивом build dist Vue приложенийРабота со стилями и CSS в Vue js для красивых интерфейсовСоздание и структурирование Vue.js приложенияКак исправить ошибку cannot find module vueНастройка и сборка проектов Vue с использованием современных инструментовИнтеграция Vue с Bitrix для корпоративных решенийРазработка административных панелей на Vue js
Функция append в Go GolangОтображение компонента mounted - практическое руководствоХуки жизненного цикла компонентов - полное руководство для разработчиковУничтожение компонента destroyed - как правильно очищать ресурсы и подпискиИнициализация данных в состоянии created - как и когда подготавливать данные в приложенииОбновление компонента beforeUpdate во VueМонтирование компонента - хук beforeMount в VueРазрушение компонента во Vue - beforeDestroy и beforeUnmountСоздание экземпляра beforeCreate - полный разбор жизненного цикла
5 библиотек для создания tree view во VueИнтеграция Tailwind CSS с Vue для современных интерфейсовИнтеграция Vue с серверной частью и HTTPS настройкамиКак обрабатывать async операции с Promise во VueИнтеграция Node.js и Vue.js для разработки приложенийРуководство по интеграции Vue js в NET проектыПримеры использования JSX во VueГайд по импорту и регистрации компонентов на VueМногоязычные приложения на Vue с i18nИнтеграция FLIR данных с Vue5 примеров использования filter во Vue для упрощения разработки3 примера реализации drag-and-drop во Vue
Слоты компонента - концепция и практическое использованиеРегистрация компонентов component-registration в приложениях с внедрением зависимостейProps компонента в React - полный разбор с примерамиФункциональные компоненты в React - функциональный подход к построению интерфейсовСобытия компонента - events в современных интерфейсахДинамические компоненты - dynamic-componentsСоздание компонента component - практическое руководствоАсинхронные компоненты async-components - практическое руководство
Наблюдатели watchers - от паттерна до практических реализацийУправление переменными и реактивными свойствами во VueИспользование v for и slot в VueПрименение v-bind для динамической привязки атрибутов в VueУправление пользователями и их данными в Vue приложенияхСоздание и использование UI Kit для Vue приложенийТипизация и использование TypeScript в VuejsШаблоны Vue templates - практическое руководство для разработчиковИспользование шаблонов в Vue js для построения интерфейсовИспользование Swiper для создания слайдеров в VueРабота со стилями и стилизацией в VueСтруктура и особенности Single File Components SFC в VueРабота со SCSS в проектах на Vue для стилизацииРабота со скроллингом и прокруткой в Vue приложенияхПрименение script setup синтаксиса в Vue 3 для упрощения компонентовИспользование scoped стилей для изоляции CSS в компонентах Vue3 способа улучшить навигацию Vue с push()Обработка запросов и асинхронных операций в VueРеактивность Vue reactivity - как это работает под капотом и как этим пользоватьсяПонимание и использование provide inject для передачи данных между компонентамиПередача и использование props в Vue 3 для взаимодействия компонентовПередача данных между компонентами с помощью props в Vue jsУправление property и функциями во Vue.jsРабота со свойствами компонентов VueУправление параметрами и динамическими данными во VueОпции компонента в Go - паттерн component-optionsРабота с lifecycle-хуком onMounted во VueОсновы работы с объектами в VueПонимание жизненного цикла компонента Vue js на примере mountedИспользование модальных окон modal в Vue приложенияхИспользование методов в компонентах Vue для обработки логикиИспользование метода map в Vue для обработки массивовИспользование хуков жизненного цикла Vue для управления состоянием компонентаРабота с ключами key в списках и компонентах VueОбработка пользовательского ввода в Vue.jsРабота с изображениями и их оптимизация в VueИспользование хуков жизненного цикла в VueОрганизация сеток и гридов для верстки интерфейсов на VueСоздание и управление формами в VueОрганизация файлов и структура проекта Vue.jsКомпоненты Vue создание передача данных события и emitРабота с динамическими компонентами и данными в Vue3 способа манипулирования DOM на VueРуководство по div во VueИспользование директив в Vue и их расширенные возможностиОсновы и применение директив в VueИспользование директив и их особенности на Vue с помощью defineИспользование компонентов datepicker в Vue для выбора датОрганизация циклов и итераций во VueКак работает компиляция Vue CoreВычисляемые свойства computed во Vue.jsСоздание и использование компонентов в Vue JSОбработка кликов и пользовательских событий в VueИспользование классов в Vue для организации кода и компонентовИспользование директивы checked для управления состоянием чекбоксов в VueГайд на checkbox компонент во VueОтображение данных в виде графиков с помощью Vue ChartСоздание и настройка кнопок в VueСоздание и настройка кнопок в Vue приложенияхРабота с lifecycle-хуками beforeCreate и beforeMount во VueОсновы Vue - vue-basics для уверенного стартаИспользование массивов и методов их обработки в VueИспользование массивов и их обработка в Vue
Использование Vuetify для создания современных интерфейсов на VueИспользование transition во VueТестирование компонентов и приложений на VueТелепортация - архитектура и реализация в серверных приложенияхРабота с teleport для управления DOM во VueSuspense в React - управление асинхронными данными и ленивой загрузкойПять шагов по настройке SSR в VuejsИспользование Shadcn UI компонентов с Vue для продвинутых интерфейсовИспользование router-link для навигации в Vue RouterКак использовать require в Vue для динамического импорта модулейРабота с динамическим рендерингом и виртуальным DOM на Vue.jsИспользование ref для управления ссылками и реактивностью в Vue 3Использование Vue Pro и его преимущества для профессиональной разработкиПлагины Vue vue-plugins - полное практическое руководствоРуководство по nextTick для работы с DOMМиксины - mixins в современном программированииJSX в Vue с использованием плагина vue-jsxСоздание и использование компонентов с помощью Vue js и CУправление состоянием и реактивностью через inject и provideДинамическое обновление компонентов и данных на VueГлубокое изучение документации Vue и как эффективно её использоватьКастомные элементы - Custom Elements в современном JavaScriptИспользование Crystal с Vue для разработкиИспользование вычисляемых свойств для динамического отображения данных на Vue jsОптимизация производительности и предупреждения в Vue
Открыть базу знаний

Лучшие курсы по теме

изображение курса

Vue 3 и Pinia

Антон Ларичев
AI-тренажерыAI-тренажеры
Практика в студииПрактика в студии
Гарантия
Бонусы
иконка звёздочки рейтинга4.8
3 999 ₽ 6 990 ₽
Подробнее
изображение курса

TypeScript с нуля

Антон Ларичев
AI-тренажерыAI-тренажеры
Практика в студииПрактика в студии
Гарантия
Бонусы
иконка звёздочки рейтинга4.8
3 999 ₽ 6 990 ₽
Подробнее
изображение курса

Next.js - с нуля

Антон Ларичев
AI-тренажерыAI-тренажеры
Практика в студииПрактика в студии
Гарантия
Бонусы
иконка звёздочки рейтинга4.7
3 999 ₽ 6 990 ₽
Подробнее

Отправить комментарий