# Project Structure Skill 本 skill 定义项目的分层架构和文件组织规范,用于指导 Agent 在创建新页面、组件时遵循统一的目录结构。 ## 核心原则 1. **页面放在 `pages/`** - 每个页面一个目录,包含 `index.vue` 2. **组件放在 `components/`** - 公共组件直接放目录下,页面专属组件按页面名分子目录 3. **页面专属组件与页面同名** - 如 `home` 页面的组件放在 `components/home/` 4. **使用 easycom 自动加载** - 无需手动 import,组件通过文件路径自动生成标签名 ## 组件放置规则(重要) ### 公共组件(跨页面复用) 当用户要求创建**公共组件**时,直接放在 `components/` 根目录下: ``` components/ ├── backNav.vue # 通用返回导航栏 ├── tabBar.vue # 通用底部栏 ├── modal.vue # 通用弹窗 └── ... ``` 标签名:``、``、`` ### 页面专属组件(仅特定页面使用) 当组件只在某个页面内使用时,放在 `components/{pageName}/` 子目录下: ``` components/ ├── home/ # 首页专属组件 │ ├── status.vue │ └── overview.vue ├── message/ # 消息页专属组件 │ └── list.vue └── bluetooth/ # 蓝牙页专属组件 └── device.vue ``` 标签名:``、``、`` ### 判断依据 | 需求描述 | 放置位置 | 示例 | |----------|----------|------| | "做一个通用的返回导航" | `components/backNav.vue` | `` | | "做一个通用的弹窗组件" | `components/modal.vue` | `` | | "首页的项目列表组件" | `components/home/projectList.vue` | `` | | "消息页的消息列表" | `components/message/list.vue` | `` | | "蓝牙页的设备卡片" | `components/bluetooth/device.vue` | `` | ## 目录结构 ``` src/ ├── pages/ # 页面目录 │ ├── home/ # 首页 │ │ └── index.vue │ ├── report/ # 报告页 │ │ └── index.vue │ ├── message/ # 消息页 │ │ └── index.vue │ ├── bluetooth/ # 蓝牙页 │ │ └── index.vue │ └── work/ # 工作页 │ └── index.vue │ ├── components/ # 组件目录 │ ├── backNav.vue # 公共组件:通用返回导航栏 │ │ │ ├── home/ # 首页专属组件 │ │ ├── homeNav.vue # 首页导航栏 │ │ ├── overview.vue # 今日作业概览 │ │ ├── status.vue # 实时作业状态 │ │ ├── projectList.vue # 项目列表容器 │ │ ├── list.vue # 项目列表项 │ │ ├── progress.vue # 项目作业进度 │ │ ├── construction.vue # 当前施工段 │ │ ├── warning.vue # 异常警告容器 │ │ └── warning_list.vue # 异常警告项 │ │ │ ├── message/ # 消息页专属组件 │ │ └── list.vue # 消息列表项 │ │ │ └── bluetooth/ # 蓝牙页专属组件 │ └── device.vue # 蓝牙设备卡片 │ ├── composables/ # 组合式函数 ├── store/ # Pinia 状态管理 ├── api/ # 接口请求 ├── utils/ # 工具函数 ├── static/ # 静态资源 └── layouts/ # 布局组件 ``` ## 命名规范 ### 文件命名 - **页面**: `index.vue`(固定) - **组件**: `camelCase.vue`(如 `projectList.vue`) - **组合式函数**: `useXxx.ts`(如 `useCount.ts`) ### 组件标签名(easycom 规则) - **公共组件**: `backNav.vue` → `` - **页面专属组件**: `home/status.vue` → `` - **嵌套组件**: `home/list.vue` → `` ### easycom 自动扫描规则 ```json { "easycom": { "autoscan": true, "custom": { "^wd-(.*)": "@wot-ui/ui/components/wd-$1/wd-$1.vue", "^uni-(.*)": "@dcloudio/uni-ui/lib/uni-$1/uni-$1.vue" } } } ``` ### easycom 自动生成标签名规则 | 文件路径 | 自动生成标签名 | |----------|----------------| | `components/backNav.vue` | `` | | `components/modal.vue` | `` | | `components/home/status.vue` | `` | | `components/message/list.vue` | `` | | `components/bluetooth/device.vue` | `` | ## 组件拆分原则 ### 何时拆分组件 1. **模板超过 100 行** - 拆分为子组件 2. **重复使用的 UI 块** - 提取为独立组件 3. **逻辑独立的功能块** - 拆分便于维护 ### 拆分模式 ``` 页面容器组件(如 projectList.vue) └── 列表项组件(如 projectList_list.vue) 页面容器组件(如 warning.vue) └── 列表项组件(如 warning_list.vue) ``` ### 示例:项目列表 ``` components/home/ ├── projectList.vue # 容器:卡片标题 + card-body └── projectList_list.vue # 内容:项目信息 + 参数 + 操作按钮 ``` 使用方式: ```vue ``` ## 创建新页面步骤 1. **创建页面目录** ``` src/pages/{pageName}/index.vue ``` 2. **创建页面专属组件目录**(如需要) ``` src/components/{pageName}/ ``` 3. **配置路由**(如需要) ```json // src/pages.json { "path": "pages/{pageName}/index", "type": "page", "style": { "navigationBarTitleText": "页面标题" } } ``` 4. **使用组件** ```vue ``` ## 页面专属组件 vs 公共组件 | 类型 | 位置 | 标签名 | 示例 | |------|------|--------|------| | 公共组件 | `components/` 根目录 | `{name}` | `` | | 页面专属组件 | `components/{pageName}/` | `{pageName}-{name}` | `` | ## 页面样式规范 ### 内容区域样式 所有使用自定义导航栏(``)的页面,`.content` 容器必须使用以下样式: ```css .content { padding: 16px; padding-top: 72px; } ``` - `padding-top: 72px` 为导航栏预留空间,避免内容被遮挡 - `padding: 16px` 保持左右边距一致 ### 卡片样式规范(重要) 每个组件自身就是一个卡片,**页面不要用额外的 `.card` 容器包裹组件**,否则多个组件会合并成一个卡片。 **卡片间距规则**: - 卡片之间间距统一为 **12px** - 页面通过 `gap: 12px` 设置间距,**组件内部不要添加 margin** - 组件只负责自身样式(背景、圆角、内边距),不负责与其他组件的间距 **正确做法** - 页面用 gap 设置间距: ```vue ``` **错误做法** - 组件添加 margin 影响间距: ```css /* 错误:组件添加 margin */ .card { margin-bottom: 16px; /* 不要用 margin */ } ``` **组件卡片统一样式:** ```css .card { background: #fff; border-radius: 12px; padding: 16px; margin-bottom: 16px; } ``` **例外情况** - 多个子组件需要合并展示时: 当明确要求将多个组件放在同一个卡片内时,由最外层容器组件统一设置卡片样式,子组件背景透明: ```css /* 容器组件 */ .container { background: #fff; border-radius: 12px; padding: 16px; } /* 子组件 */ .child { background: transparent; padding: 0; } ``` ### 页面模板示例 ```vue ``` ### 字体规范 项目使用三级字体体系: | 级别 | 字号 | 用途 | 示例 | |------|------|------|------| | 一级 | 22px | 最大标题 | 页面标题、卡片大标题 | | 二级 | 18px | 次级正常字体 | 正文、列表项、表单标签 | | 三级 | 14px | 最小描述字体 | 辅助说明、placeholder、元信息 | **CSS 变量:** ```css /* 一级标题 */ --font-size-title: 22px; /* 二级正文 */ --font-size-body: 18px; /* 三级描述 */ --font-size-caption: 14px; ``` **使用示例:** ```vue ``` ## 注意事项 1. **不要在页面中直接写大段模板** - 超过 100 行考虑拆分 2. **组件样式使用 scoped** - 避免样式污染 3. **组件 props 要有默认值** - 提高组件易用性 4. **事件命名使用 kebab-case** - 如 `@handle-click` 5. **插槽优先于 props 传内容** - 灵活性更高 6. **禁止使用 git 提交** - 代码的改动必须经过手动提交 ## UI 组件库使用规范(重要) 项目使用两套 UI 组件库,按场景分工: ### uni-ui(表单/表格场景) **仅用于**表单、表格相关的组件: - 下拉选择:`` - 单选框:`` / `` - 多选框:`` / `` - 日期选择:`` - 输入框:`` - 数据选择器:`` - 图标:`` 官网:https://uniapp.dcloud.net.cn/component/uniui/uni-data-select.html ### wot-ui(其他所有场景) **除表单表格外**,其他所有 UI 组件统一使用 wot-ui: - 按钮:`` - 图标:`` - 弹窗:`` - 导航栏:`` - 标签:`` - 步骤条:`` - 加载:`` - 等等 ### 快速判断 | 场景 | 使用库 | 组件示例 | |------|--------|----------| | 输入框 | uni-ui | `` | | 下拉选择 | uni-ui | `` | | 单选/多选 | uni-ui | `` / `` | | 日期时间选择 | uni-ui | `` | | 按钮 | wot-ui | `` | | 图标 | wot-ui | `` | | 弹窗/通知 | wot-ui | `` / `` | | 导航栏 | wot-ui | `` | | 标签/徽标 | wot-ui | `` / `` | | 表格展示 | uni-ui | `` |