AI沉淀出来的一些前端开发rules

70 阅读24分钟

Vue 3 + TypeScript 通用开发规范(质量下限 + 安全)

定位与全局观

  • 适用范围:任意 Vue 3 + TypeScript 前端(中后台、数据看板、埋点 SDK/管理端安全监测、官网、低代码宿主等)。具体业务子目录命名(如 views/orderviews/mall)由 README / 项目级规则 规定;本节「目录与模块边界」规定通用分层职责与依赖方向,与业务域名称无关。UI 组件库选型由项目自行约定。
  • 对 AI / 开发者的期望:交付物应稳定可维护(判空、错误态、契约清晰)、安全合规(密钥与敏感数据)、结构清晰(可拆分、可演进)。无论产品是「订单」还是「事件上报」,同一套下限均适用。
  • 与 README 的关系接口成功判定、业务错误码、HTTP 语义README.md 为准(第二节)。环境变量命名前缀、文件上传限制、错误上报方式、a11y 达标要求等若与「行业默认」不同,也应在 README 或 README 链接的文档中写明;本规则只写原则,不写死具体工具与阈值。
  • 原则:不得低于目标仓库已有 根目录工程基座(见第五节:ESLint、Prettier、Stylelint、TypeScript、vue-tsc、Commitlint 等)所定义的基线;只允许同等或更严。上不封顶。

目录与模块边界(通用)

目标:任意接手仓库的人(含 AI)能判断「新文件该放哪、谁能依赖谁」,避免跨域耦合与循环依赖。

1. 推荐 src/ 分层职责

以下目录名为常见约定;若仓库使用 pages/ 代替 views/stores/ 代替 store/ 等,等价映射即可,但职责应一致。

目录职责
api/HTTP 调用、请求/响应类型禁止写页面状态、路由、业务 UI 分支。按后端域或业务域分子目录。
views/pages/路由级页面;可含本页专用子组件、本页 composable(或迁入 hooks/ / composables/)。
components/跨页面复用的展示与交互;宜再分 基础/通用业务共享(子目录或命名前缀区分),避免业务细节污染底层组件。
hooks/composables/可复用的组合式逻辑(请求+状态、表单、表格等),无路由耦合为佳。
store/stores/全局或跨路由会话态禁止把仅单页使用的列表状态默认升仓,除非 README 约定。
router/路由表、守卫、元信息;禁止在路由文件内写大块业务逻辑,应委托 composable/store。
utils/纯函数、与组件实例无关的工具;禁止依赖具体页面或 router 单例(特殊封装除外并在 README 说明)。
types/全局 TS 类型、.d.ts;领域类型优先靠近使用方或 api/ 同模块。
assets/图片、字体等静态资源。
config/plugins/directives/layout/locales/按项目既有结构放置;新增类目录须在 README 或项目规则 中记一笔,避免一人一套。
典型 src/ 目录树(任意 Vue 3 + TypeScript 项目均可采用;业务子目录名由 README 自定)

以下为与业务无关的参考骨架;viewsapi 下的下一级文件夹(如 orderadmintelemetry)不在此写死,由 README 列出「域 ↔ 路径」映射即可。

src/
├── api/                 # 按业务域/资源分子目录;仅 HTTP 与类型
├── assets/              # 静态资源
├── components/          # 跨页复用组件(可再分子目录:base、business 等)
├── composables/         # 或 hooks/,任选其一或并存但职责不重复
├── config/              # HTTP 客户端、应用级配置(可选,依项目)
├── constants/ 或 constant/ # 全局常量、枚举映射(可选,与 types 区分)
├── directives/          # 自定义指令(可选)
├── layout/ 或 layouts/  # 壳层布局(可选)
├── locales/             # 或 i18n/(可选)
├── plugins/             # Vue 插件注册(可选)
├── router/              # 路由
├── store/ 或 stores/    # 全局状态(可选)
├── styles/              # 全局样式(可选)
├── types/               # 全局类型
├── utils/               # 纯工具函数
└── views/ 或 pages/     # 路由页面;域级子目录与 api/ 对齐
  • 小型项目可删减空目录;大型项目可增加 services/constants/lib/ 等,但须在 README 说明职责,且不破坏上文依赖方向。
  • Monorepo 子应用:每个应用各自具备完整或精简的 src/,本节约束按应用根生效。

2. 组织策略(二选一为主,全仓库一致)

  • 按技术分层api/*views/*components/* 清晰分离;适合中后台与多域并列。
  • 按功能域(feature)features/order/{api,components,pages} 等;适合域边界强、团队按域分工。

混合时须约定:域内可就近放子文件,域间共享须通过 components/hooks/api/ 等公共层,禁止 views/domainA 深层 import views/domainB 的内部实现文件。

3. 依赖方向(必须)

  • 单向依赖页面 →(api / hooks / components / store)→ utils / types禁止 utilsviewsapiviews、子业务页 → 另一业务页内部文件。
  • 禁止明显 循环依赖(A→B→A);出现时用 类型-only import、拆共享模块或下沉 utils 解决。
  • 路径别名(如 @/)仅缩短路径,不改变上述分层语义。

4. api/ 与页面

  • 同一后端资源:api 模块与 views 模块在目录命名上应对齐(具体命名表见 README 或项目级规则)。
  • 页面内禁止手写裸 axios URL 字符串散落;必须经统一客户端与 api/ 内函数(与第二节 README 契约一致)。

5. barrel 文件(index.ts 聚合导出)

  • 谨慎在大型目录根使用 barrel 再导出全部,易引发 循环引用tree-shaking 变差;优先 按需路径导入有限导出列表。若项目统一使用 barrel,须在 README 说明规范。

6. 与 README / 项目规则的关系

  • 本文件:规定「放什么类代码、谁依赖谁」及通用 src/ 骨架适用于所有 Vue 3 + TypeScript 仓库(拷贝时勿删本节)。
  • README(或各仓库自己的项目级规则):规定路径别名业务域文件夹命名api/<域>views/<域> 对照表)、以及本仓库相对上图的增删目录
  • 冲突时:结构纪律以更严、更贴近本仓库 README 者为准。

7. public/src/assets/(应用根目录下,与 src/ 并列,通用)

  • public/(Vite 等约定名,或构建工具等价目录):构建时原样输出到站点根不经模块打包与按内容哈希重命名。适用于 faviconrobots.txt、需固定 URL** 供外链/第三方回调引用的文件。在模板或 HTML 中通常用 根相对路径(如 /logo.svg),**不要**按 ES 模块 import
  • src/assets/:经 import / SFC 引用 进入依赖图,可享受 文件名哈希、压缩、按需 等构建优化。适用于 组件内图片、与打包相关的资源
  • 禁止将本可受益于打包管线的大资源误放 public/ 导致体积与缓存策略失控;禁止将须稳定不变路径的文件误放 src/assets/ 导致部署后 URL 变化破坏外链。例外须在 README 写明。

一、硬性禁止(违反即视为不合格)

1. 空值与类型安全

  • 禁止在未判空/未收窄类型的情况下访问嵌套属性或调用方法(a.b.carr[0].x;可选链能表达意图时优先使用)。
  • 禁止as 粗暴断言掩盖未校验的数据结构;确需断言时应已有运行时校验或明确的不变式说明。
  • any:默认禁止;仅在第三方类型缺失等窄场景使用,且应局限在最小范围(并优先考虑 unknown + 校验/收窄)。

2. 模板与指令

  • 禁止在同一元素上同时使用 v-ifv-for。应改为:外层 template v-for + 内层 v-if,或先用计算属性/过滤后的列表渲染。
  • v-for必须提供稳定、可预测的 :key(优先业务主键;避免仅用索引,除非静态列表且无副作用)。

3. 结构与可维护性

  • 禁止单函数过长(建议 ≤ 80 行为常态上限;超过应拆分)。严禁单函数数百行。
  • 禁止单文件组件无节制膨胀(建议 .vue ≤ 400 行为警戒;超过应拆子组件、composables、纯模块)。严禁单文件上千行堆叠。
  • 禁止setup 或单一函数中混杂无关职责(I/O、领域规则、展示状态搅在一起);应分层或拆分。

大文件拆分顺序(必须)composables(状态、异步与数据契约、领域规则),展示型子组件禁止只拆模板、核心逻辑仍堆在父组件。

4. 异步、接口与状态

  • 禁止在未确认「本次调用在约定意义上成功且载荷可用」时,直接使用业务字段驱动核心 UI。
  • 禁止忽略 loading / 错误态 / 空数据态,导致静默失败或误导。
  • 禁止无意义的空 catch;须记录、兜底 UI 或按统一策略向上抛出。

5. 反例模式(领域无关)

以下属于不合格:请求返回后不先按项目约定判断成功与否,仅按「像数组或带 list/data」猜测结构就当作有效数据使用。

// 反例:未按统一成功判定,易把失败响应当列表用
const res = await api.getList()
const list = Array.isArray(res) ? res : (res?.list ?? res?.data ?? [])

合格方向:先按 README.md(或 README 指向的契约文档)HTTP 客户端/拦截器实际行为 判定成功,再读取载荷,并对数组/对象做校验与默认值。

6. 路由与 URL 输入

  • route.paramsroute.query 及任何来自 URL 的字符串视为不可信输入;用于 跳转、拼请求、权限判断必须校验格式与取值范围(正则、白名单、与当前会话上下文比对等,细节以 README 为准)。
  • 禁止将 query 中的 redirect、完整 URL、外链未经验证与白名单即用于 window.locationrouter.push,防止开放重定向。
  • 数字/枚举类 ID:转换后须校验有效(如 Number.isFinite、正整数、UUID 格式等按 README),再发起请求。

7. 写操作与重复提交

  • 创建、更新、支付、提交表单等写操作:请求进行中必须通过 loading + 禁用触发控件等价互斥锁禁止因连点、双击、重复触发导致并发重复提交。
  • 若 README/后端约定 幂等键(Idempotency-Key) 等机制,必须按约定携带;禁止在未读契约时自行发明不一致的 header/body 字段名。

8. 高风险载荷的运行时校验

  • README 中列出或团队公认的高风险路径(如资金、权限、安全策略、关键配置、不可逆操作的数据依赖):在 HTTP 成功之后、驱动核心业务之前必须运行时形状校验zod / valibot / 手写守卫等,工具以 README 为准)。校验失败须走错误分支,禁止当成功路径继续渲染或提交。
  • 禁止仅依赖 TypeScript as 或「猜字段」消费上述载荷。

二、接口与响应契约(以 README 为准)

本节不写死具体数值或字段名;唯一事实来源为仓库 README.md 中与后端/API 相关的约定(成功码、失败形态、错误提示字段、不存在资源时的 HTTP 行为等)。若契约写在其它文件,README 须指向该文件,AI 与开发者实现前必须先读

必须遵守的纪律(与具体码值无关)

  • 禁止在未阅读 README 契约的情况下,凭猜测拼接「可能是 list/data/数组」来使用响应。
  • 必须按 README 约定区分:HTTP/网络层失败业务层失败(含各自如何提示用户);二者不得混用一种处理方式导致重复提示或静默失败。
  • 若响应体含业务成功/失败标识(如 codesuccess 等,以 README 为准):须在能访问到该字段时按 README 判断;禁止在失败语义下仍把载荷当成功数据驱动核心 UI。
  • 若 HTTP 客户端 拦截器 在失败时 reject、成功时 unwrap 只返回 data:调用方仍须理解「等价于已在拦截器侧按 README 判定成功」,禁止在契约未澄清时假设 unwrap 结果一定可用。
  • 禁止假设列表载荷一定为数组;须 Array.isArray 或 README 约定的类型守卫后再迭代。
  • README 缺失或契约含糊:应先补写 README 或与维护者对齐后再写接口消费代码,禁止长期依赖未文档化的口头约定。

三、安全与数据边界(必选)

  • 密钥与凭证禁止在源码、规则、注释、提交记录中硬编码 token、密码、私钥;使用环境变量或构建注入;含秘密的 .env* 不得提交版本库。
  • 配置与环境变量禁止在业务代码中写死生产基址、环境差异大的开关等;须从 构建时环境变量README 约定的运行时配置接口读取。仓库必须提供可提交的 .env.example(或 README 中的变量表),列出变量名、含义、是否必填与占位示例不得包含真实秘密;新增配置须先更新 example/文档再写代码(变量前缀如 VITE_* 等以 README 为准)。
  • XSS:用户可控内容须按项目方案处理(默认转义、v-html 与富文本须白名单/消毒);禁止为省事绕过。
  • 权限与敏感数据:无权限能力须隐藏或禁用(实现方式依项目);展示侧对手机、证件等 脱敏
  • 请求与输入:不信任仅前端校验;前端校验只改善体验,不作为安全边界依据。
  • 依赖禁止引入来源不明的脚本或外链处理敏感数据;依赖须可审计。
  • 日志与可观测性禁止向控制台、日志平台、错误上报 payload 输出 token、密钥、完整 Cookie、未脱敏 PII;须使用 README 约定的统一上报/日志封装(若项目尚未接入,至少集中一处可替换封装,禁止业务层散落裸 console 作为唯一手段)。生产构建的 source map 策略(是否上传、是否仅内网)以 README/运维为准。
  • Vue 运行时错误渲染、setup、组合式 API 中发生的未捕获错误,须有统一处理入口(如应用级 app.config.errorHandler、布局/根组件 onErrorCaptured 等,具体写法以 README 与项目入口为准)。禁止console.error 而无 用户可感知提示或与 统一上报/日志封装 的衔接,导致生产白屏或客诉无据可查;禁止在业务侧随意 try/catch 吞掉错误且不上报、不提示。
  • 埋点 / 上报 / 监测类功能禁止向第三方或日志系统上报 token、密钥、完整 Cookie、未脱敏 PII;事件名与 payload 宜 类型化,采集逻辑与页面展示 解耦(独立模块或 composable),避免每个按钮复制粘贴上报代码。

四、文件上传与下载(Blob)

具体大小、类型、个数、是否分片README 为准;本节为通用纪律。

  • 下载(Blob / 文件流)禁止在未按 README/拦截器约定确认「响应为预期文件」时直接触发保存;若错误响应可能被包装为 200 + JSON/HTML,须按项目约定检查 Content-Type、魔术字节或解析探测禁止将错误页当文件落盘且无提示。
  • 上传:选择文件后、发起请求前必须校验 大小、个数、允许的 MIME/扩展名(阈值与清单以 README 为准);超限须明确提示禁止无任何校验直接转发任意文件体。
  • 大文件或长传:必须支持或与 README 一致地实现 取消(如 AbortController 及与 组件卸载 一致的清理,避免泄漏与无效回调。

五、根目录工程基座与质量工具(通用)

以下文件通常位于仓库根目录(或 packages/<app>/ 根目录 in monorepo),与业务域无关,可在 Vue 3 + TypeScript 项目间整套拷贝再按 README 微调具体规则条目以各文件内容为准;本节规定必须具备哪些类工具、职责分工与纪律

1. 为何通用

  • 同一套工具链保证:任意成员与 AI 产出的代码在 风格、可疑模式、类型、样式、提交说明 上与仓库一致,减少「仅本地能过、他人一拉就红」的摩擦。
  • 拷贝到新项目时:优先保留 文件名与脚本约定(如 lint:eslintlint:stylelint),替换 extends/插件版本 即可,不必重发明目录里的哲学。

2. 建议具备的根目录配置(按职责)

类别常见文件名职责(通用)
ESLint.eslintrc.cjs / .eslintrc.jseslint.config.*.eslintignoreJS/TS/Vue 逻辑:未使用变量、any 滥用、Vue 最佳实践、与 TS 解析器配合等。
Prettierprettier.config.*.prettierrc.prettierignore格式化(引号、换行、尾逗号);与 ESLint 重复规则时须在配置中 分工(常见:eslint-config-prettier 关掉格式冲突)。
Stylelintstylelint.config.*.stylelintignoreVue SFC 中 <style>、SCSS/Less/CSS 的质量与约定(顺序、禁止未知 @ 规则等)。
TypeScripttsconfig.jsontsconfig.app.json编译选项与路径别名;与 vue-tsc / Vite 共用。
Vue 类型检查脚本如 vue-tsc --noEmitSFC 与类型;是否进 CI 由 README 说明。
Commitlintcommitlint.config.*提交信息格式(常与 Conventional Commits 一致:feat:fix: 等),便于 changelog 与 code review。
Git 钩子(可选)huskylint-staged提交前对暂存区跑 eslint/prettier/stylelint,缩短反馈环。
编辑器(可选).editorconfig.vscode/extensions.json / settings.json 推荐缩进、换行符;推荐安装 ESLint、Prettier、Vue 等扩展,不强制提交个人 IDE 全局设置。

3. 与「单事实来源」的关系

  • Lint/Format 的细则:以仓库内 实际配置文件 为准;本文件逐条抄录规则 ID。Commitlinttype-enumsubject-* 等以 commitlint.config.* 为准(第五节 §7 为说明与默认表)。
  • README 建议补充:当前项目启用了哪些命令(如 pnpm lint:eslint)、CI 是否强制执行、Commitlint 是否与 husky 绑定。新成员与 AI 实现前可一眼看到。

4. 对开发与 AI 的纪律

  • 禁止为图省事在业务代码中 大面积 eslint-disable / prettier-ignore;确需关闭须 窄范围 + 注释说明原因
  • 新增代码不得 无故抬高 既有告警级别或引入与 Prettier 冲突的手写格式(在已有 format 脚本的前提下)。
  • 提交信息须符合 Commitlint(若仓库已配置),格式与 type 表见第五节 §7禁止随意使用未出现在 type-enum 中的 type(除非先改配置与团队约定)。
  • 不要求每次 AI 任务末尾必须本地执行 lint(与历史约定一致);但交付的代码在风格与规则上应视为能通过当前仓库配置。

5. 新仓库最小清单(可复制检查表)

  • ESLint(含 Vue + TypeScript 支持)+ .eslintignore
  • Prettier + 与 ESLint 不打架的集成
  • Stylelint(若使用 SFC/SCSS)+ .stylelintignore
  • tsconfig + 构建/IDE 一致
  • (推荐)Commitlint + Conventional Commits
  • (推荐)lint-staged + husky
  • README 中 一行说明:pnpm lint:* 或等价命令

6. 依赖与 lockfile(通用)

  • 禁止为解决同一类问题并列引入多套职能重叠的主流基础库(如多套路由级 HTTP 封装、多套日期库),除非 README 说明迁移中或边界用途。
  • 可复现安装:须将 lockfilepnpm-lock.yamlpackage-lock.jsonyarn.lock 等,以项目为准)纳入版本控制禁止在无团队约定的情况下删除 lockfile 或长期依赖未锁版本的 latest / * 拉取生产依赖。
  • 主版本与破坏性升级:升级前须阅读 CHANGELOG / Release Notes,评估构建与运行时影响;禁止在未同步 README 或迁移说明 的情况下大范围跳主版本。
  • 漏洞审计:按团队节奏执行 pnpm audit / npm audit(或 CI),对已知高危依赖按流程修复或记录经批准的例外。

7. Commitlint 与约定式提交(通用)

  • 定位:与 Conventional Commits 对齐,便于 changelog、发版、Code Review 扫一眼知意图。具体校验规则以仓库根目录 commitlint.config.*(或 package.jsoncommitlint 字段)为唯一事实来源;本节为推荐形态与常见 type 表,若配置与本文不一致以配置为准
  • 推荐脚手架extends: ['@commitlint/config-conventional'],再按团队收紧或扩展 rules
  • 标题格式(最常见)<type>[(optional scope)]: <subject>
    • 空行后可有 body破坏性变更可用 ! 置于 type 后,或在 footer 写 BREAKING CHANGE:(与 Conventional Commits 一致,具体以所用 preset 为准)。
  • type(须小写、非空):以下为跨项目推荐枚举(与常见 config-conventional + 团队扩展一致);若仓库删减或新增 type,须同步改 commitlint.config 并在 README 一句说明。
type含义(简述)
feat新功能
fix缺陷修复
docs文档
style纯格式(不影响代码含义)
refactor重构(非 feat 非 fix)
perf性能优化
test测试相关
chore构建、辅助工具、杂项
revert回滚提交
build构建系统或外部依赖
ciCI 配置
  • subject(主题)禁止为空;禁止以英文句号 . 结尾(与常见 subject-full-stop 规则一致);宜 简洁、祈使语气(如「fix 登录态丢失」而非「fixed」)。主题大小写是否约束以 commitlint.configsubject-case 为准。
  • 对 AI / 开发者的纪律:生成 commit message 时使用已配置type禁止编造未出现在 type-enum 中的类型(如随意 updatewip),除非团队已写入配置。禁止整句粘贴进 subject 过长无重点;较大说明放 body
  • 与 Git 钩子:若使用 husky 等在 commit-msg 调用 commitlint,本地失败即修正后再提交,避免 CI 与本地不一致。

六、建议性规范(推荐,提升上限)

在已满足第一~五节前提下,用于可读性、复用性与演进成本。

1. 组合式函数(Composables)

  • 导出命名 useXxx;单 composable 围绕一个清晰用例(如分页列表、表单草稿、上报通道初始化)。
  • 变厚时迁入异步与README 所载数据契约拆展示子组件;对外暴露 ref / computed / 方法,实现细节可隐藏。
  • 返回值用普通对象便于解构;需保护的可 readonly() 或仅暴露方法。
  • 重复 ≥2 处的「请求 + 状态 + 错误处理」再提取,避免过早抽象。

2. 计算属性、方法与模板

  • 模板保持简洁;复杂判断与数据处理进 computed 或纯函数。
  • 可缓存的派生状态用 computed;依赖事件入参的用方法。
  • 避免深层嵌套三元,改用命名 computed 或早返回函数。

3. 常量与魔法值

  • 与后端或领域约定的字面量用 as const / 枚举 / 命名常量 集中管理。
  • 格式化、脱敏等与 UI 框架无关的逻辑进 utils 或独立模块,便于测试。
  • 除广泛约定的数字外,魔法数应有命名(如 DEBOUNCE_MS)。

4. 副作用:watch / 生命周期

  • 优先 watch 显式数据源;慎用无依赖清单的 watchEffect
  • deep: true 仅在有必要时开启,并评估性能与循环触发。
  • 异步请求须处理 竞态(序号、AbortControlleronScopeDispose 等与项目一致);禁止在组件销毁后仍写入状态。
  • 多个并行请求可统一 loading,避免 UI 闪动不一致。

5. 组件契约

  • defineProps / defineEmits 使用 TypeScript 形态,事件名与载荷类型明确。
  • 属性透传遵循 Vue 3 $attrs 惯例,避免重复声明。

6. 注释与命名

  • 注释解释 「为什么」;导出模块可简述 用途与前置条件
  • 命名用完整语义;布尔用 is/has/should;与外部 API 字段映射处可简短标注。

7. 性能(按需)

  • 非首屏路由与大体积依赖:懒加载(异步组件或路由级)。
  • 大列表:虚拟列表或等价方案;搜索输入 防抖/节流
  • 稳定且昂贵的子树可按文档评估 v-memo;大对象可考虑 shallowRef / markRaw(明确场景)。

8. 表单与本地状态

  • 校验规则宜 片段复用(常量或工厂函数),减少复制。
  • 使用 localStorage / sessionStorage 等时:键名集中定义敏感数据不落明文(与第三节一致)。

9. 横切能力(埋点、监控、配置中心)

  • 采集与展示分离:上报、轮询探针、SDK 初始化等放在 独立模块 + composable,页面只调用稳定 API(如 track(event, payload)),payload 有类型定义
  • 失败可感知:上报失败宜有策略(重试队列、降级、采样),避免静默丢数且无据可查(实现深度依产品,本节为方向性要求)。
  • 配置与开关:环境相关配置从 环境变量或运行时配置 注入,禁止写死环境差异大的 URL/开关。

10. 可访问性(a11y)

  • 表单与可编辑控件:须有可感知的 标签关联label/aria-labelledby 等,与所选 UI 库推荐写法一致)。
  • 对话框、抽屉等浮层:打开后键盘焦点可进入浮层内控件,关闭后不将焦点留在已卸载节点(优先使用组件库内置行为;若自研须按 README 约定实现)。
  • 禁止为省事移除组件库自带的 语义角色、焦点管理 等可访问性属性;关键路径应键盘可达(与 README 中 a11y 等级目标一致)。

11. 编码与可读性细节(函数、数据边界、组件)

以下提升 可读性与维护性,与第一节「硬性禁止」及第三节「异常」配合;偏 Vue / TypeScript 成熟工程习惯(含与 Vue 生态相近的写法),不绑定具体 UI 库。

  • 函数参数:形参较多(约 ≥4)或含多个可选/布尔开关时,优先 options 对象 + interface/type 标注,避免一长串 positional 参数难以记忆与传错序。
  • 布尔参数避免 foo(a, true, false, true) 无自解释性;改用 对象字段名(如 { immediate: true })或 字面量联合(如 mode: 'sync' | 'async')。
  • 控制流:对 null/非法输入/无权限 等先 早返回 或独立分支,再写主流程;避免四层以上嵌套 if 才把「正常路径」写在最深处。
  • 纯函数命名:数据整形、解析、缺省填充可用 normalize*resolve*ensure*create* 等前缀,使调用处一眼知「在做什么」。
  • 接口数据边界:在 api 返回之后、进入多个视图之前(或在专用 composable 内)将响应 规范化为内部类型/结构,减少模板与业务里重复的 ?. 链与形状猜测(与第二节 README 契约一致)。
  • 异步 UI 状态:优先 status 判别联合(如 'idle' | 'loading' | 'success' | 'error')或等价 有限状态避免多个独立 booleanloading/error/empty)易不同步。
  • 魔法比较:除 README 已约定的 业务码 等外,业务类型、Tab 索引等禁止裸数字/裸字符串散落;用 命名常量、as const 映射或枚举
  • 组件职责展示props + emit 为主;请求、路由副作用、与后端的契约判断放在 父组件或 composable;易变或重绘频繁的区块 拆子组件 并保证 稳定 key(与第一节体量约束一致)。
  • 复杂初始状态:表单/大对象初始值用 createEmptyXxx() 或小工厂,避免在多个组件复制同一默认对象字面量导致引用共享 bug。
  • 开发态代码:断言、冗长调试日志、仅开发可见的校验放在 import.meta.env.DEV(或 README 约定的等价开关)内,避免无分支地打进生产包体积与噪音(与第三节「日志」衔接)。
  • 分支与异常:业务上「失败 / 空数据 / 取消」分支 显式命名(如 if (!ok) return + 注释或封装 handleXxxError),禁止把成功逻辑与错误处理搅在同一深层块中;catch 空吞、仅 console 仍须遵守 第一节与第三节

七、与项目级补充文档的关系

  • 本文件为 跨项目通用下限(含目录职责与依赖方向)。
  • README.md(及其中链接的契约文档)API、配置前缀、文件限制、上报方式、a11y 目标lint/CI 命令入口等的权威来源,优先于本文件对具体实现的历史记忆。
  • 根目录 *.config.*.eslintrc.*tsconfig*.json具体规则条目的权威来源(见第五节)。
  • 各仓库项目级规则(若有)该仓库路径别名、脚手架特有目录、业务域名的权威来源,与本文「目录与模块边界」配合使用。
  • 各仓库可另有 项目级规则(目录、UI 库、i18n、路由命名等)。冲突时取更严者;业务脚手架以项目文档为准。

八、后续可迭代条目(非必须)

可按需在副本中增补:provide/inject 类型策略、全局状态库边界、路由守卫与鉴权细则、E2E/单测策略;提交与分支规范若未用 Commitlint,可在 README 单独约定。