命名规范
TIP
规定前端项目中文件、目录、变量、组件、接口等的命名方式,适用于 Vue 3 + TypeScript + Vite 技术栈,并与 目录规范 保持一致。
设计原则
| 原则 | 说明 |
|---|---|
| 见名知意 | 名称应准确表达用途,避免 data、temp、handler 等模糊命名 |
| 风格统一 | 同类事物使用同一种命名风格,全项目保持一致 |
| 英文优先 | 代码标识符使用英文,中文仅用于注释与文案 |
| 避免缩写 | 除通用缩写(如 id、url、api)外,不使用难懂缩写 |
| 禁止拼音 | 不使用拼音或拼音缩写,如 yonghuList |
命名风格
| 类型 | 风格 | 示例 |
|---|---|---|
| 目录 / 非组件文件 | camelCase | userMng/、tagsView.ts |
| Vue 组件文件 | PascalCase | GvUserInfo.vue、GvNavBar.vue |
| 功能首页文件 | PascalCase + 'Index' 后缀 | UserMngIndex.vue、RoleMngIndex.vue |
| 功能子页文件 | PascalCase | UserEdit.vue、RoleEdit.vue |
| 组件注册名 | PascalCase | <GvUserInfo />、<GvNavBar /> |
| 变量 / 函数 | camelCase | searchUserData、dialogVisible |
| 功能模块页'name' | PascalCase | name: 'UserIndex' |
| 组合式函数 | camelCase + use 前缀 | useStyle、useSecret |
| 接口 / 类型 | PascalCase | FormItem、MessageType |
| 枚举 | PascalCase(枚举名)+ PascalCase(成员) | UserStatus.ENABLE |
| 常量 | UPPER_SNAKE_CASE | ICON_PREFIX |
| 环境变量 | UPPER*SNAKE_CASE + VITE* 前缀 | VITE_API_BASE_URL |
| CSS 类名 | kebab-case / BEM | user-list、user-list__item |
| 路由 path | camelCase | /sysMng/userMng/UserMngIndex |
| 路由 name | PascalCase | UserMngIndex |
| i18n key | camelCase | title |
| API 名 | camelCase + 'Api' 后缀 | findUsersApi |
| GvForm 参数:ref | camelCase + 'SearchFm' 后缀 | userSearchFm |
| GvForm 参数:ref-form | camelCase + 'SearchFm' 后缀 | userSearchFm |
| GvForm 参数:form-list | camelCase + 'SearchList' 后缀 | userSearchList |
| GvTable 参数: ref | camelCase + 'TableList' 后缀 | userTableList |
| GvTable 参数: ref-table | camelCase + 'TableList' 后缀 | userTableList |
| GvTable 参数: table-head | camelCase + 'TableHeadList' 后缀 | userTableHeadList |
| GvTable 参数: table-data | PascalCase + 'search' 前缀 + 'Data' 后缀 | searchUserData |
目录与文件命名
目录
- 使用 camelCase 小驼峰英文
- 名称使用名词或名词短语,体现业务域
typescript
✅ userMng/
✅ companyMng/
❌ UserMng/
❌ user-mng/
❌ user_mng/
❌ yonghu/文件
| 文件类型 | 命名规则 | 示例 |
|---|---|---|
| Vue 页面/组件 | PascalCase | UserMngIndex.vue |
| TypeScript 模块 | camelCase | bizConf.ts |
| 类型定义 | /types/index.ts | userMng/types/index.ts |
| 测试 | <name>.spec.ts / <name>.test.ts | UserMng.spec.ts |
| 样式(独立文件) | kebab-case | element-plus.scss |
禁止
同一目录下不要混用 UserList.vue 与 user-list.vue 两种组件文件风格。
组件命名
单文件组件
- 文件名:PascalCase,与组件名一致
- 多词组合,避免与 HTML 原生标签冲突
vue
<!-- ✅ UserList.vue -->
<script setup lang="ts">
// 组件名与文件名一致
defineOptions({ name: 'UserMngIndex' });
</script>组件层级语义
| 类型 | 前缀/后缀建议 | 示例 |
|---|---|---|
| 页面级 | 业务 + 页面类型 | UserMngIndex.vue、UserEdit.vue |
| 布局 | PascalCase | Layout.vue |
| 通用基础组件 | 业务无关名词 | GvNavBar.vue、GvEcharts.vue |
| 业务组件 | 模块 + 功能 | UserForm.vue、UserTable.vue |
Props / Emits / Slots
typescript
// props:camelCase
const props = defineProps({
visible: propTypes.bool.def(false),
rowData: propTypes.object,
operateType: propTypes.string
});
// emits:camelCase 动词或动词短语
const emit = defineEmits(['update:visible', 'saved']);
// slots:camelCase(模板中使用)
// <slot #title />TypeScript
变量与函数
typescript
// ✅ 变量:名词 / 名词短语
const searchUserData = ref<Recordable<any>>({});
const rowData = ref<Recordable<any>>({});
// ✅ 函数:动词开头,切记不要使用function关键字
const saveUser = async () => {}
const editUser = async () => {}
const updateUserStatus = async () => {}
// ✅ 布尔值:is / has / can / should 前缀
const isVisible = ref<boolean>(true)
const hasPermission = computed<boolean>(() => ...)类型与接口
typescript
// 接口:PascalCase,不加 I 前缀
interface UserInfo {
id: string;
userName: string;
}
// 类型别名:PascalCase
type UserId = string;
// 枚举:PascalCase
enum OrderStatus {
Pending = 'PENDING',
Completed = 'COMPLETED'
}常量
typescript
// 真正不可变、全局共享的使用 UPPER_SNAKE_CASE
export const MAX_PAGE_SIZE = 100;
export const DEFAULT_LOCALE = 'zh-CN';hook
- 文件名:
use+ PascalCase 语义 →useEcharts.ts - 导出函数:与文件名一致
typescript
// useEcharts.ts
export function useEcharts<T>(options: EchartsOptions<T>) {
// ...
}常见前缀约定:
| 前缀 | 用途 | 示例 |
|---|---|---|
use | 组合式逻辑 | useUtil、useI18n |
on | 事件监听封装 | onClick |
create | 工厂函数 | createMessage |
to | 转换类 | toUserDTO |
Store
typescript
// 文件名:kebab-case 或 camelCase
// stores/modules/user.ts
export const useUserStore = defineStore('user', () => {
state: (): UserState => ({
userInfo: undefined,
}),
getters: {
getUserInfo(): UserInfo | undefined {
return this.userInfo;
}
},
actions: {
setUserInfo() {
// ...
}
}
});| 项 | 规则 | 示例 |
|---|---|---|
| Store ID | camelCase | 'user'、'order' |
| Store 函数 | use + PascalCase + Store | useUserStore |
| State | camelCase 名词 | userInfo |
| Action | camelCase 动词 | setUserInfo |
路由
typescript
// path:camelCase,体现层级
{ path: '/sysMng/userMng', name: 'UserMngIndex' }
// 动态参数:camelCase
{ path: '/user/:userId' }| 项 | 规则 | 示例 |
|---|---|---|
| path | camelCase | userMngIndex |
| name | PascalCase,与页面组件对应 | UserMngIndex |
| params | camelCase | :userId、:orderId |
| query | camelCase | ?pageSize=20¤tPage=1 |
API
typescript
// 函数:动词 + 业务对象 + Api后缀
export const findUsersApi = (datas: Recordable<any>) => {};| 函数前缀 | 示例 |
|---|---|
接口名称 + Api | findUserApi |
TypeScript
export const findUsersApi = (datas: Recordable<any>) => {
const { fetch } = useFetch();
if (import.meta.env.VITE_NODE_ENV !== 'production') fetch.getInstance().defaults.baseURL = baseUrl;
return fetch.post(`${server.gateway_admin}/sysuser/findUsers`, datas);
};CSS
优先使用 BEM 或 kebab-case,组件内样式加 scoped。
scss
<style scoped lang="scss">
// 块__元素--修饰符
.user-list {
}
.user-list__header {
}
.user-list__item--active {
}
// 状态类:is- / has- 前缀
.is-disabled {
}
.has-error {
}
</style>| 类型 | 规则 | 示例 |
|---|---|---|
| 类名 | kebab-case | search-bar |
| BEM 块 | kebab-case | user-form |
| 修饰符 | -- 连接 | user-form__input--error |
| 全局工具类 | 简短语义 | text-center、flex-between |
Guava UI
使用 Guava UI 组件时,优先沿用组件库提供的 class 与 token,减少自定义类名冲突。
多语言
详见 多语言规范,基本约定如下:
typescript
<功能模块>.<文案标识>
export default {
common: { → 通用功能
homePage: 'HomePage', → 首页文案
login: 'Login', → 登录文案
},
// more ...
}- key使用 camelCase
- value: 如无特殊情况,第一个单词首字母大写,其余单词均小写
- 层级 2 级
表格/表单
通常我们的表格与表单是动态配置的,在业务模块中占用的行数太多,导致代码的可读性不好,因此将这部分代码抽离,使业务模块的代码更简洁。
| 变量 | 函数命名 | 示例 |
|---|---|---|
table-head | createTableHeadList(单表头) | create<功能模块>TableHeadList(多表头) | createTableHeadList({editUser,adduser}) \| createUserTableHeadList({editUser,adduser}) |
form-list | createSearchList(单表单) | create<功能模块>SearchList(多表单) | createSearchList({handleBlur, dicSelectedCB}) | createUserSearchList({handleBlur, dicSelectedCB}) |
变量与函数
typescript
// ❌
const d = ref([]);
const fn = () => {};
function getData() {}
// ✅
const searchUserData = ref<Recordable<any>>({});
const searchUserList = async () => {};组件
vue
<!-- ❌ list.vue -->
<!-- ❌ userlist.vue -->
<!-- ✅ UserList.vue -->类型
typescript
// ❌
interface IUser {}
type userInfo = {};
interface getUserListRequest {}
// ✅
interface UserInfo {}
type UserDTO = {};
interface GetUserListReq {}命名 Checklist
提交代码前自查:
- 目录与 TS 文件使用 camelCase,组件文件使用 PascalCase
- 变量、函数使用 camelCase,常量使用 UPPER_SNAKE_CASE
- 组件名、类型名使用 PascalCase,且为多词组合
- hook 以
use开头,Store 以useXxxStore命名 - API 函数以Api后缀结尾,语义需尽量与 HTTP 动作一致
- 无拼音、无无意义缩写、无
data1/temp/test1类临时命名 - GvTable 与 GvForm 组件的参数是否完全按照
【命名风格速查】进行命名