命名规范
BBC 8.0 前端使用 Vue 3、TypeScript 和 pnpm workspace。命名首先表达所属应用、业务语义和公开边界,其次才追求简短。
文件与目录
| 类型 | 规则 | 示例 |
|---|---|---|
| 可复用 Vue 组件 | PascalCase | PageActionBar.vue、GoodsBaseInfo.vue |
| 路由页面 | kebab-case | goods-list.vue、seller-order-list.vue |
| composable | use + PascalCase | useLogin.ts、useConfirmAction.ts |
| API、工具、配置模块 | kebab-case | after-sale.ts、route-components.ts |
| 包或应用目录 | 小写 kebab-case | packages/components、apps/seller |
| 公开 barrel | index.ts | packages/api/index.ts |
| 样式文件 | kebab-case | backend-table.scss |
| 图片 | 小写 kebab-case,包含用途 | placeholder-image.png |
已有历史文件可能不完全符合新规则。不要为了统一命名做无收益的大范围重命名;修改时保持导入、路由、权限 identifier 和公开入口完整。
TypeScript 标识符
| 类型 | 规则 | 示例 |
|---|---|---|
| 变量、函数 | camelCase | goodsList、loadGoods() |
| Vue 组件、类、类型、接口 | PascalCase | TableLayout、GoodsListItem |
| 常量 | UPPER_SNAKE_CASE | DEFAULT_PAGE_SIZE |
| 布尔值 | is、has、can、show、enable 开头 | isLoading、hasPermission |
| 事件处理器 | handle 开头 | handleSave()、handlePageChange() |
| 数据加载 | load 或 fetch 开头 | loadDetail()、fetchChildren() |
| API 查询 | get 开头 | getGoodsList() |
| API 写入 | create、update、delete、业务动词 | updateGoods()、cancelOrder() |
不要继续使用 GET_GoodsList、POST_UserData 这类把 HTTP method 写进函数名的旧命名。HTTP 方法已经由请求配置表达,函数名应描述业务动作。
// 推荐
const loading = ref(false);
const selectedGoodsIds = ref<string[]>([]);
async function loadGoodsList() {}
function handleSelectionChange() {}
临时变量也应有语义,不使用 _tempArray 作为通用命名。下划线前缀只用于明确表示“有意未使用”的函数参数,以匹配 ESLint 配置。
路由与权限名称
新增 Admin/Seller 页面 route name 使用 lowerCamelCase,并与后端菜单 identifier 完全一致:
page({
path: "/goods/example-list",
name: "exampleList",
title: "exampleList",
});
以下名称是登录和根布局等既有基础路由:Login、Root、Dashboard。不要以此为由给新业务页面使用 PascalCase。
动态路由组件映射使用相同 key:
export const routeComponents = {
exampleList: () => import("@/views/goods/example-list.vue"),
};
路由重命名会影响后端菜单、角色权限、隐藏页 backName 和缓存,不能只改前端字符串。
API 与后端字段
- 请求函数按业务动作命名,不在名称中重复端前缀;端归属由目录和 namespace 表达。
- Admin/Seller barrel 使用
AdminXxxApi、SellerXxxApi命名空间。 - 后端请求与响应字段保持原始 snake_case,例如
page_no、data_total、goods_id。 - 后端 Long 或雪花 ID 使用 string,名称仍保留
_id或Id的既有契约,不附加Number。 packages/api/models的生成类型名与后端 VO/DTO/DO 对齐,不为了前端偏好随意重命名。
import { AdminGoodsApi } from "@/api";
const result = await AdminGoodsApi.getGoodsList({
page_no: 1,
page_size: 20,
});
Vue props、events 与 v-model
- TypeScript 中 prop 使用 camelCase,模板中使用 kebab-case。
- 组件事件在 TypeScript 中按实际事件字符串声明,模板监听使用 kebab-case。
- 默认 v-model 使用
modelValue和update:modelValue。 - 多个 v-model 应使用清晰名称,例如
visible和update:visible。
const props = defineProps<{ modelValue: string; maxLevel?: number }>();
const emit = defineEmits<{ "update:modelValue": [value: string] }>();
<CategoryPicker
v-model="categoryId"
:max-level="4"
@changed="handleCategoryChange"
/>
CSS class
页面和组件 class 使用小写 kebab-case,并采用稳定的 block、element、modifier 关系:
<section class="goods-list-page">
<div class="goods-list-page__toolbar"></div>
<div class="goods-list-page__item goods-list-page__item--disabled"></div>
</section>
- 不使用无语义的
.red、.left1、.box2。 - 不使用随机缩写;
btn、sku、api等团队已理解的术语可以保留。 - JavaScript 行为优先通过状态和组件事件表达,不额外创建
.js-*选择器耦合 DOM。 - 不用 TDesign 内部 class 作为业务组件名称。
环境变量与功能开关
浏览器环境变量必须以 VITE_ 开头并使用 UPPER_SNAKE_CASE:
VITE_API_ADMIN
VITE_DOMAIN_PC
VITE_LIVEVIDEO
功能开关名称应与 config/features.ts 的 key 保持一致,不能在页面定义同义别名。
装修模块
- 模块目录和 Vue 组件使用 PascalCase,例如
GoodsSlider/GoodsSliderPreview.vue。 - 保存到装修数据中的模块
name使用 kebab-case,例如goods-slider。 - 设置组件使用
XxxSetting.vue,预览组件使用XxxPreview.vue。 aliases当前只参与部分布局识别,不会自动注册 Preview 别名。模块name、目录和 Preview 组件名应在归一化后保持一致。
检查
命名变更后执行:
pnpm lint
pnpm typecheck
涉及路由、公共导出或文件移动时还要构建受影响应用,并用全局搜索确认旧名称只保留在明确的兼容映射中。