开发规范
11
类别: 
vortmall前端Admin开发

开发规范

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
评论 0
/ 1000
0
0
收藏