# 前端目录结构 > Vue 3 前端工程的目录职责与命名约定。 ## 目录职责 ```text oci-portal-dash/ ├── package.json 脚本 dev / build / typecheck / lint / format ├── vite.config.ts @ 别名指向 src/;dev 代理 /api → localhost:8080 ├── .env.development VITE_MOCK=1,开发默认走内置 mock 数据 ├── index.html └── src/ ├── main.ts 应用入口,挂 Pinia 与 router ├── App.vue NConfigProvider 注入 Naive 主题 ├── assets/ main.css:Tailwind @theme 设计 token(浅色)+ html.dark 暗色变量覆盖与全局基础样式 ├── theme/ tokens.ts(JS 侧 token 唯一来源,含 darkTokens 暗色板)、naive.ts(亮暗两套 themeOverrides 同一工厂生成) ├── types/ api.ts:与后端 swagger(oci-portal/docs/)一一对应的 DTO 类型 ├── api/ request 封装(JWT 注入、401 跳登录、错误 hint 拼接)+ 按资源分模块;VITE_MOCK=1 时返回 mock.ts 数据 ├── stores/ Pinia:auth(令牌持久化)、app(侧栏收缩、暗色主题:默认跟随系统 + localStorage 记忆,驱动 html.dark 与 Naive darkTheme)、scope(全局作用域:租户/区域/区间,localStorage 按租户记忆) ├── router/ 路由与登录守卫 ├── composables/ useAsync(异步状态)、useFormat(时间/字节/OCID 格式化)、useRegionAlias(区域友好名)、useTransientPoll(过渡态自动轮询:实例电源 / 挂载操作后每 5 秒刷新至稳态) ├── components/ StatusBadge、OcidText、CostChart 等复用组件;表单基座 FormModal / FormField(hint 问号 tooltip + error / feedback 下置提示)/ FormSection(分组标题)/ FilePicker(含 compact 单行态)/ AppInputNumber(数字框统一封装:右侧垂直上下箭头步进);tenant/ 下为租户详情各 tab 与失联占位 DeadPlaceholder(失联时整体替换 tab 内容),storage/ 下为引导卷编辑 / 挂载弹窗,task/ 下含 CronEditor 可视化编辑器与任务表单(tab 分类型),instance/ 下含 InstanceSpecForm(实例规格表单,创建实例弹窗与抢机任务共用),logs/ 下为日志页各 tab 面板(SystemLogPanel 系统日志、LogEventPanel 回传日志) ├── layouts/ AppLayout(顶栏 + 内容区,顶栏右侧为全局作用域租户 / 区域选择器)、SidebarNav(分组导航、收缩态) └── views/ 页面:登录、总览、租户列表/详情、实例列表/详情、网络、VCN 详情、引导卷列表(编辑 / 挂载 / 删除以弹窗内联完成,无单独详情页)、任务、日志(tab 结构:「系统日志」操作留痕,预留回传日志)、设置(tab 结构:「通知」通知管理 + Telegram 配置,「任务」抢机熔断阈值)等 ``` ## 全局作用域约定 租户 / 区域在顶栏右上角全局选择,区间在各资源列表页内选择,三者经 scope store 全站共享——实例 / 网络 / 引导卷页跟随同一作用域查询单租户数据,切页无需重选;选择按租户记忆在 localStorage,未开启多区域 / 多区间支持的租户对应选择器禁用锁定默认值。租户导入 / 修改 / 删除 / 测活、订阅新区域成功后经 `scope.refreshConfigs()` 即时刷新全局选择器,无需刷新页面。 ## 命名约定 - `src/` 下按职责分层:`views/`(页面)、`components/`(复用组件)、`composables/`、`api/`(接口封装)、`stores/`(Pinia)、`types/`、`assets/`。 - 组件文件 PascalCase(`TaskLogDrawer.vue`),composable/工具文件 camelCase,路由路径 kebab-case。 - `api/` 模块按后端资源划分(`instances.ts`、`tasks.ts`…),函数名与接口语义对应,不散调 axios。