App
App — сущность приложения, которая описывает всё, что необходимо для запуска приложения и его настройки. Здесь находятся ключевые вещи, которые нужны только для запуска самого приложения.
Важность уровня
Данный уровень исключительно важен, так как именно он помогает начать исследование: как приложение работает в целом и куда смотреть дальше. Поэтому важно, чтобы в нём было минимальное количество логики и максимальное количество конфигураций и интеграций. При ознакомлении с новым проектом этот уровень — лучший вариант для начала исследования. После могут быть изучены уже существующие страницы и модули.
Возможное альтернативное название:
boot— оно точно выражает суть: запуск приложения и инициализация основных компонентов
Как понять, что сущность — это часть App?
- Это относится непосредственно к старту приложения и его настройке
- Это не какая-то переиспользуемая логика
- Это какая-то конфигурация или интеграция с внешним сервисом, которая важна для всего приложения
Типичная структура
Полный пример структуры App
Выберите файл в дереве слева
Пример использует контракт публичного API analytics: googleAnalytics.init(trackingId: string): void. Реализация SDK остаётся внутри модуля; entry.ts вызывает настройку из app.
Работа с интеграциями
Что такое интеграция?
Интеграция — это не готовая логика для переиспользования по проекту, а конфигурация и начальные инициализации для работы с внешним сервисом.
Как другие могут это использовать?
Для этого используется IoC (Inversion of Control). Вы реализуете сущность или сервис, в которую в app будет подставляться конкретная реализация или конфигурация.
Пример интеграции
// modules/Analytics/index.ts
export interface AnalyticsClient {
track(event: string): void
}
export function createAnalytics(client: AnalyticsClient) {
return { pageOpened: () => client.track('page_opened') }
}// app/integrations/analytics.ts
import { createAnalytics } from '@/modules/Analytics'
export const analytics = createAnalytics({
track(event) {
void fetch('/api/events', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ event }),
keepalive: true
}).catch(() => { /* Телеметрия не блокирует страницу. */ })
}
})
analytics.pageOpened()Работа с конфигурациями
Конфигурации работают схоже с интеграциями. Их основная задача — собрать в одном месте все конфигурации для приложения. Это упрощает настройку и контроль в будущем, а также позволяет отделить логику от настроек.
Работа с Layouts
Layouts — лейауты чаще всего используются для настройки общего вида приложения, и их части особо нигде не переиспользуются. Поэтому они комфортно чувствуют себя в app-уровне.
Для реализации отдельных компонентов Layouts можно создать уровень /app/ui и в нём создать отдельные компоненты. Выбор лейаута должен происходить в настройках роутера.
Подробно о том почему это работает именно так вы можете прочитать в разделе Где хранить....
Работа с роутером
Тут всё как вы привыкли в других проектах. Импортируете роутер из папки /router и используете его в main.ts или entry.ts.
Что делать с выносом имён роутов?
Вы можете поместить URL-пути в /common/constants/routes.ts и использовать их в роутере и в коде:
// common/constants/routes.ts
export const ROUTES = {
HOME: '/',
ABOUT: '/about',
PRODUCTS: {
LIST: '/products',
DETAIL: (id: string) => `/products/${encodeURIComponent(id)}`,
}
}Пути используются при навигации; они не заменяют описания маршрутов в app/router.ts.
<!-- pages/index.vue -->
<script setup lang="ts">
import { ROUTES } from '@/common/constants/routes'
import { RouterLink } from 'vue-router'
</script>
<template><RouterLink :to="ROUTES.PRODUCTS.LIST">Каталог</RouterLink></template>Можно ли выносить роуты в модули?
Можно, и если это уместно, то даже нужно. Модули могут экспортировать свои роуты, которые затем импортируются в основной роутер:
// modules/Auth/routes.ts
import type { RouteRecordRaw } from 'vue-router'
export const authRoutes: RouteRecordRaw[] = [
{ path: '/auth/login', component: () => import('./pages/login.vue') }
]