开发规范

开发规范

1. 代码风格

1.1 格式化(Prettier)

  • 统一使用 Prettier 做代码格式化,避免手工调整风格。
  • 配置文件.prettierrc.json
    • tabWidth: 4
    • printWidth: 160
    • semi: true
    • singleQuote: false(统一双引号)
    • trailingComma: none
    • endOfLine: lf
  • 命令npm run format(对 src/ 执行写入式格式化)

1.2 代码规范检查(ESLint)

  • 配置文件eslint.config.ts(flat config)
  • 启用规则集
    • eslint-plugin-vueflat/essential
    • @vue/eslint-config-typescriptrecommended
    • @vue/eslint-config-prettier/skip-formatting:跳过与 Prettier 冲突的格式化规则
  • 忽略目录dist/dist-ssr/coverage/
  • 命令npm run lint(默认带 --fix --cache

1.3 类型检查(TypeScript / vue-tsc)

  • 类型检查命令npm run type-checkvue-tsc --build
  • 严格构建npm run build:strict(先类型检查,再构建)
  • 路径别名@/* -> src/*(见 tsconfig.json / tsconfig.app.json

1.4 开发/构建脚本(Vite)

  • npm run dev:本地开发
  • npm run build:构建产物
  • npm run preview:本地预览构建产物

1.5 换行、编码、尾空格(EditorConfig)

  • 配置文件.editorconfig
  • 统一约束
    • charset = utf-8
    • trim_trailing_whitespace = true
    • end_of_line = lf

2. 命名与文件组织

2.1 命名规范

  • 变量 / 函数camelCase
  • 类型PascalCaseUserInfoPaginatedResult
  • 组件PascalCaseUserCard.vueLoginAgreement.vue
  • 常量UPPER_SNAKE_CASE(仅对真正的常量使用)

2.2 文件与目录命名

  • 页面目录(views):业务域用 kebab-case(如 admin-merchant/after-sales/
  • 页面文件
    • 入口页统一 Index.vue
    • 详情页用 Detail.vue(如需要)
    • 表单页用 Form.vue(如需要)
  • 组件文件:统一 PascalCase.vue
  • Hook / Composable 文件useXxx.ts(如 useCrudPage.tsuseTenantPath.ts
  • 导出聚合:目录 index.ts 作为统一出口(如 components/common/**/index.tsstores/index.ts
  • 禁止项
    • 文件名包含空格(例如 xxx copy.vue
    • 文件名包含 copynew 等临时标记

2.3 导入约定

  • 路径优先用别名@/xxx,避免 ../../..
  • 类型导入:优先 import type { ... } from "..."
  • 环境变量读取:只从 import.meta.env 读取。

3. Vue 组件开发规范

3.1 SFC 写法

  • 默认使用<script setup lang="ts">
  • 页面/组件命名:使用 defineOptions({ name: "Xxx" })(便于调试/KeepAlive/埋点)
  • Props / Emits
    • props 命名使用 camelCase(模板中可使用 kebab-case
    • 需要默认值的 props 必须给默认值

3.2 组件自动导入(Vort UI)

  • 组件自动导入由 unplugin-vue-components + 自定义解析器 VortResolver 实现(见 vite.config.tssrc/components/vort/resolver.ts)。
  • 允许两种写法(无需手动 import)
    • <vort-button />(kebab-case)
    • <VortButton />(PascalCase)
  • 类型声明文件:自动生成到 src/components.d.ts(不要手改,避免被覆盖)。

3.3 Teleport 挂载点

  • 根组件 App.vue 内提供 #vort-teleport-container 作为统一挂载点,弹层类组件应优先挂载到该容器,确保层级与 CSS 变量继承一致。

4. 路由规范(Vue Router)

4.1 路由组织

  • 路由入口:src/router/index.ts
  • 路由守卫:src/router/guards.ts
  • 模块路由:src/router/routes/**

4.2 多租户 URL 约定

  • 多租户解析工具:src/utils/business/tenant.ts
  • 关键原则:
    • URL 是唯一上下文源:优先从 URL 解析 tenantIdadminType(token 解码后得到 shop/vendor/...
    • 需要租户的端必须在 URL 中同时包含 tenantIdadminType token,缺失视为旧链接并重定向
    • 导航拼接租户前缀时使用 resolveTenantPath() / buildTenantPath(),不要手写字符串拼接

4.3 路由守卫约定

  • 白名单路由(无需登录):/login
  • 未登录:无 accessToken 时跳转 /login
  • 动态菜单加载:首次进入需要按权限加载菜单并注入路由(由 menus 相关 store/util 实现)

5. 状态管理规范(Pinia)

5.1 Store 组织

  • store 入口:src/stores/index.ts
  • 模块 store:src/stores/modules/*.ts
  • 推荐写法:defineStore("xxx", () => { ... })(Composition API store)

5.2 持久化与运行时上下文

  • 使用 pinia-plugin-persistedstate
  • 仅持久化可跨标签共享的最小数据(当前约定:accessTokenuserInfo)。
  • adminType 以 URL 为准
    • 不依赖 localStorage 的 adminType 残留值
    • afterHydrate 后从 URL 同步到 store
  • 每标签页隔离的数据(例如店铺/供应商运行时信息)使用 sessionStorage,并以 tenantId + adminType 作为 key 维度隔离。

6. 请求与接口规范(Axios)

6.1 统一请求入口

  • 统一封装:src/api/request.ts
  • 再导出入口:src/utils/request.ts(禁止绕开封装直接使用 axios)

6.2 环境变量与 baseURL

  • baseURL 由环境变量拼接:
    • VITE_BASE_URL
    • VITE_REQUEST_URL_PREFIX(可被单次请求 config.prefix 覆盖)

6.3 环境变量清单(项目实际读取)

  • 路由 baseVITE_BASE_DIR(用于 createWebHistory 与 Vite base
  • 请求 baseVITE_BASE_URL
  • 请求前缀VITE_REQUEST_URL_PREFIX
  • 默认登录账号(平台端)
    • VITE_DEFAULT_USER_NAME
    • VITE_DEFAULT_USER_PASSWORD
  • 默认登录账号(商户端/门店端)
    • VITE_DEFAULT_STORE_NAME
    • VITE_DEFAULT_STORE_PASSWORD

6.3 请求头约定

  • satoken:从 localStorage.accessToken 读取
  • X-ADMIN-TYPE:从 store 读取,URL 兜底
  • X-ClIENT-TYPE:固定为 admin
  • 多租户 header:
    • X-Shop-Id:商户端/门店端
    • X-Vendor-Id:供应商端

6.4 FormData 上传

  • config.dataFormData 时不手动设置 Content-Type,避免 boundary 丢失。

6.5 响应结构与错误处理

  • 统一响应结构src/types/api.d.ts):
    • code: number
    • message: string
    • data: T
  • 成功条件code === 0
  • 失败条件code > 0
    • 统一 reject,错误对象至少包含 code/message/data
  • 登录失效
    • code === 401 或 HTTP 401/403:触发登出流程(userStore.logout()
  • 禁止项
    • 页面中重复写 try/catch + toast 逻辑(优先复用封装与统一提示)
    • 在业务层随意吞掉错误(除非明确标注“额外数据获取,不影响主流程”)

7. 业务 Hook / 组合式函数规范

7.1 Hook 目录与职责

  • src/hooks/:面向页面/业务场景的 Hook(如 useCrudPageuseDialogForm
  • src/composables/:更通用的组合式工具(如租户路径处理)

7.2 useCrudPage 约定(列表页统一模式)

  • useCrudPage 负责:
    • 分页参数(page/size)与列表加载
    • 搜索提交与重置
    • 表格排序
    • 选中行与批量操作
  • 失败提示使用 @/components/vort/message,避免各页自行实现重复提示逻辑。

8. 样式规范(Tailwind / SCSS / Less)

8.1 全局样式入口

  • src/assets/styles/index.css
    • Tailwind v4:@import "tailwindcss";
    • 动画库:@import "tw-animate-css";
    • @theme inline / CSS 变量作为主题映射基础
  • src/theme/index.scss
    • Vort 主题变量与全局覆盖(配合 variables.scss

8.2 新增样式优先级

  • 优先:Tailwind 工具类(与 CSS 变量配合)
  • 需要全局一致时:写入 src/theme/index.scss
  • 仅影响当前组件时<style scoped>,跨组件覆盖使用 :deep()
  • Less 使用场景:既有页面已使用 <style lang="less" scoped>,新增保持与页面一致即可

9. 注释与可维护性

9.1 注释风格

  • 对外导出的函数/工具/复杂逻辑使用 JSDoc(含 @param@returns、示例)。
  • 注释目标:
    • 解释“为什么这么做”(why),而不是重复代码本身(what)。

9.2 错误类型与 unknown

  • catch (error) 后优先以 unknown 处理,再做最小必要的类型收窄/断言。
  • 避免把 any 作为默认方案(除非在封装层做兼容兜底)。

10. 图片与截图(文档配图)

  • 建议放置目录:docs/文章文档/assets/
  • 命名建议:yyyyMMdd_模块_主题.png(例如 20260128_登录_验证码流程.png
开发规范
请输入搜索内容
大纲
开发规范
1. 代码风格
1.1 格式化(Prettier)
1.2 代码规范检查(ESLint)
1.3 类型检查(TypeScript / vue-tsc)
1.4 开发/构建脚本(Vite)
1.5 换行、编码、尾空格(EditorConfig)
2. 命名与文件组织
2.1 命名规范
2.2 文件与目录命名
2.3 导入约定
3. Vue 组件开发规范
3.1 SFC 写法
3.2 组件自动导入(Vort UI)
3.3 Teleport 挂载点
4. 路由规范(Vue Router)
4.1 路由组织
4.2 多租户 URL 约定
4.3 路由守卫约定
5. 状态管理规范(Pinia)
5.1 Store 组织
5.2 持久化与运行时上下文
6. 请求与接口规范(Axios)
6.1 统一请求入口
6.2 环境变量与 baseURL
6.3 环境变量清单(项目实际读取)
6.3 请求头约定
6.4 FormData 上传
6.5 响应结构与错误处理
7. 业务 Hook / 组合式函数规范
7.1 Hook 目录与职责
7.2 useCrudPage 约定(列表页统一模式)
8. 样式规范(Tailwind / SCSS / Less)
8.1 全局样式入口
8.2 新增样式优先级
9. 注释与可维护性
9.1 注释风格
9.2 错误类型与 unknown
10. 图片与截图(文档配图)