本文总结了Vue3开发中的命名规范,分为强制和推荐两种级别。主要规范包括:
- 组件命名:定义时使用PascalCase(如UserProfile),模板中优先使用PascalCase标签
- Props命名:定义用camelCase(userName),模板传递用kebab-case(user-name)
- 事件命名:定义用camelCase(updateValue),监听用kebab-case(@update-value)
- 文件命名:组件文件使用PascalCase(UserProfile.vue)
- 指令命名:使用kebab-case(v-focus)
核心原则:
- JS/TS领域遵循camelCase/PascalCase
- HTML领域使用kebab-case
- 组件使用PascalCase明确标识
- 保持项目内命名一致性
规范优势:
- 利用Vue自动转换能力
- 提高代码可读性和维护性
- 明确区分组件和HTML元素
- 促进团队协作效率
按照Vue3官方风格指南(https://vuejs.org/style-guide/)和常见实践,总结命名规则。
注意:有些规则是强制的(如避免与HTML元素冲突),有些是推荐的(为了统一性)。
将规则分为以下几个类别:
-
组件命名 (Component Naming)
-
组件文件命名 (Component File Naming)
-
Props命名 (Props Naming)
-
事件命名 (Event Naming)
-
自定义指令命名 (Custom Directive Naming)
-
模板中的属性命名 (Attribute Naming in Template)
-
模板中的组件标签命名 (Component Tag Naming in Template)
-
变量命名 (Variable Naming)
注意:强制(Mandatory)和推荐(Recommended)的区分。
在Vue 3中,组件命名和使用的推荐方式如下:
组件命名(定义组件时) :推荐使用PascalCase(大驼峰)。
- 例如:
MyComponent.vue在模板中使用组件 :可以使用PascalCase 或kebab-case(连字符) 。但是,由于HTML是大小写不敏感的,在DOM模板(例如直接在HTML中使用的模板)中,必须使用kebab-case。而在单文件组件(SFC)的
<template>中,Vue编译器支持将kebab-case自动转换为PascalCase,但通常建议在SFC模板中也使用PascalCase,以保持一致性,并明确这是组件而非原生HTML元素。Props命名 :在定义props时,使用camelCase(小驼峰),在模板中使用时,可以使用camelCase(在JSX中)或kebab-case(在DOM模板和SFC模板中)。在SFC模板中,Vue会自动将kebab-case的props名转换为camelCase。
自定义事件命名 :推荐使用kebab-case ,因为在事件名中不会使用到属性名转换,且HTML属性是不区分大小写的。但是,在
defineEmits定义时,可以使用camelCase,但模板中监听时仍使用kebab-case。
总结推荐
组件定义名:PascalCase
模板中的组件标签:PascalCase(以区分原生HTML元素)
Props定义:camelCase
模板中的Props:kebab-case
自定义事件名:定义和触发时使用camelCase,模板中监听使用kebab-case
这样既符合Vue的转换规则,也符合HTML的书写习惯(HTML属性不区分大小写,通常写为kebab-case)。
同时,在模板中使用PascalCase的组件标签可以很容易地识别出哪些是自定义组件,哪些是原生HTML元素。
Vue 3 命名规则总结表
组件相关命名
| 类别 | 场景 | 推荐命名 | 强制等级 | 示例 | 备注 |
|---|---|---|---|---|---|
| 组件文件 | SFC 文件名 | PascalCase.vue | 推荐 | UserProfile.vue |
与组件名保持一致 |
| 组件定义 | JS/TS 中定义 | PascalCase | 推荐 | UserProfile |
注册/导入时使用 |
| 模板标签 | 模板中使用 | PascalCase | 推荐 | <UserProfile> |
明确区分于HTML元素 |
| 模板标签 | DOM模板 | kebab-case | 强制 | <user-profile> |
HTML不区分大小写 |
| 动态组件 | :is 绑定 | PascalCase | 推荐 | :is="UserProfile" |
保持一致性 |
| JSX/TSX | JSX中使用 | PascalCase | 强制 | <UserProfile> |
JSX区分大小写 |
Props 命名
| 类别 | 场景 | 推荐命名 | 强制等级 | 示例 | 备注 |
|---|---|---|---|---|---|
| 定义Props | JS中定义 | camelCase | 强制 | userName |
JS变量命名规则 |
| 传递Props | 模板属性 | kebab-case | 推荐 | user-name |
HTML属性规范 |
| 类型定义 | TypeScript | camelCase | 强制 | interface Props { userName: string } |
TS命名规范 |
| Boolean | 布尔属性 | 前缀is/has |
推荐 | isActive, hasError |
语义清晰 |
事件命名
| 类别 | 场景 | 推荐命名 | 强制等级 | 示例 | 备注 |
|---|---|---|---|---|---|
| 定义事件 | JS中定义 | camelCase | 推荐 | updateValue |
Vue 3 事件约定 |
| 触发事件 | emit调用 | camelCase | 推荐 | emit('updateValue') |
与定义一致 |
| 监听事件 | 模板监听 | kebab-case | 推荐 | @update-value |
HTML事件属性 |
| 自定义事件 | 复杂事件 | 动词+名词 | 推荐 | user-updated |
清晰描述动作 |
指令命名
| 类别 | 场景 | 推荐命名 | 强制等级 | 示例 | 备注 |
|---|---|---|---|---|---|
| 自定义指令 | 全局注册 | kebab-case | 强制 | v-focus |
Vue指令规范 |
| 指令钩子 | 钩子函数 | camelCase | 强制 | beforeMount |
JS函数命名 |
| 指令参数 | 指令参数 | kebab-case | 推荐 | v-tooltip:top-start |
符合HTML属性 |
变量与引用
| 类别 | 场景 | 推荐命名 | 强制等级 | 示例 | 备注 |
|---|---|---|---|---|---|
| ref引用 | 模板ref | camelCase | 推荐 | inputRef |
JS变量规范 |
| 响应式变量 | reactive | camelCase | 强制 | userData |
JS变量规范 |
| 计算属性 | computed | camelCase | 推荐 | fullName |
描述性命名 |
| 函数/方法 | 方法名 | camelCase | 强制 | getUserInfo() |
JS函数规范 |
| 常量 | 常量定义 | UPPER_SNAKE | 推荐 | MAX_SIZE |
常量约定 |
样式与类名
| 类别 | 场景 | 推荐命名 | 强制等级 | 示例 | 备注 |
|---|---|---|---|---|---|
| CSS类名 | 样式类 | kebab-case | 推荐 | .user-profile |
CSS命名惯例 |
| Scoped样式 | 组件样式 | kebab-case | 推荐 | .avatar-img |
与模板类名一致 |
| CSS变量 | CSS变量 | kebab-case | 推荐 | --primary-color |
CSS自定义属性规范 |
其他规则
| 类别 | 场景 | 推荐命名 | 强制等级 | 示例 | 备注 |
|---|---|---|---|---|---|
| 组合式函数 | composable | camelCase | 强制 | useUserStore() |
前缀use |
| 工具函数 | 工具函数 | camelCase | 强制 | formatDate() |
描述动作 |
| 类型定义 | TypeScript | PascalCase | 强制 | UserProfileProps |
TS类型命名 |
| 枚举 | 枚举类型 | PascalCase | 强制 | UserRole |
枚举成员PascalCase |
| 泛型参数 | 泛型 | PascalCase | 推荐 | T, K, V |
单个大写字母 |
强制等级说明
| 等级 | 含义 | 后果 |
|---|---|---|
| 强制 | 必须遵守,否则可能出错 | 编译错误或运行时错误 |
| 推荐 | 强烈建议遵守,最佳实践 | 代码可维护性差或团队协作问题 |
| 可选 | 个人/团队偏好 | 影响代码一致性 |
自动转换规则摘要
| 转换方向 | 是否自动 | 说明 |
|---|---|---|
| kebab-case → camelCase | ✅ 是 | 模板属性自动映射到JS属性 |
| camelCase → kebab-case | ❌ 否 | JS中定义的在模板中需手动转换 |
| PascalCase → kebab-case | ✅ 是 | 组件名在DOM模板中自动转换 |
| 事件名转换 | ✅ 是 | @update-value → updateValue |
核心原则总结
-
JS/TS领域:遵循JavaScript/TypeScript命名规范(camelCase/PascalCase)
-
模板/HTML领域:遵循HTML规范(kebab-case)
-
组件定义:使用PascalCase明确标识组件
-
一致性:在项目内保持统一
-
语义化:名称应清晰表达用途
优先级顺序(当冲突时)
-
语言/平台强制规则(如HTML属性不区分大小写)
-
框架强制规则(如Vue指令必须kebab-case)
-
官方推荐规范(Vue风格指南)
-
团队/项目约定
-
个人偏好
不同场景的详细对比
| 场景 | 推荐命名 | 说明 |
|---|---|---|
| 组件文件名 | PascalCase.vue |
UserProfile.vue |
| 组件定义名 | PascalCase |
UserProfile |
| 模板中标签 | PascalCase |
<UserProfile> |
| Props 定义 | camelCase |
userName |
| Props 传递 | kebab-case |
user-name |
| 事件定义 | camelCase |
updateValue |
| 事件监听 | kebab-case |
@update-value |
| 自定义指令 | kebab-case |
v-focus |
实际项目示例
项目结构
components/
├── UserProfile.vue // PascalCase
├── ArticleList.vue
└── ModalDialog.vue
为什么这样推荐?
技术原因:
自动转换 :Vue 编译器自动处理
kebab-case↔camelCase区分组件和元素 :
PascalCase标签明确表示这是 Vue 组件JS一致性 :JavaScript 中自然使用
camelCaseHTML兼容性:HTML 属性名不区分大小写
在 Vue 3 中,对于组件的属性(props),Vue 确实会自动将驼峰命名(camelCase)转换为连字符命名(kebab-case)。这意味着你在模板中使用连字符命名,而在 JavaScript 中使用驼峰命名,Vue 会自动进行映射。
例如,如果你定义了一个 prop 名为
innerRef,在模板中你可以使用inner-ref来传递这个属性。
但是,需要注意的是,这种自动转换只适用于 props 和自定义事件。对于其他属性,比如普通的 HTML 属性,Vue 不会进行这种转换。另外,在 Vue 3 中,这种转换行为与 Vue 2 类似,但有一些细微差别。
在 Vue 3 的模板中,你可以使用以下方式:
对于组件,如果你传递的 prop 是驼峰命名,在模板中可以使用连字符命名。
对于自定义事件,同样,在模板中监听事件时,可以使用连字符命名,而在 JavaScript 中使用驼峰命名。
然而,需要注意的是,在 Vue 3 中,对于自定义事件,推荐使用连字符命名(kebab-case)在模板中,因为 HTML 是大小写不敏感的。
但是,Vue 3 并不会自动将驼峰命名的事件名转换为连字符命名,你需要手动写连字符的形式。
不过,对于 props,Vue 会自动转换。
但是,有一点需要注意:在 Vue 3 中,如果你使用
setup函数,你在模板中使用的属性名应该与你在props中定义的名称一致(驼峰命名),但模板中可以使用连字符命名。
实际上,Vue 的编译器会在编译模板时将连字符命名的属性转换为驼峰命名,以便与 JavaScript 中的 prop 名称匹配。
总结:
- 在 Vue 3 的模板中,对于组件的 props,你可以使用连字符命名(kebab-case)来传递驼峰命名(camelCase)的 prop。Vue 会自动进行映射。
- 对于自定义事件,在模板中监听时,你需要使用连字符命名,而在定义事件时使用驼峰命名,但 Vue 不会自动转换事件名,你需要确保在模板中使用的是正确的事件名(连字符命名)。
- 在 Vue 3 中,事件名也支持使用驼峰命名,但在 DOM 模板中(即直接写在 HTML 中的模板),由于 HTML 不区分大小写,所以推荐使用连字符命名。
- 在字符串模板(如单文件组件)中,可以使用驼峰命名,但为了保持一致,通常也推荐使用连字符命名。
所以,对于 props,Vue 会自动转换,你可以在模板中使用连字符命名,而在 JavaScript 中使用驼峰命名。对于事件,在模板中监听时,建议使用连字符命名,而在定义事件时使用驼峰命名,但要注意 Vue 不会自动转换事件名,你需要手动写对应关系。
团队规范建议
-
统一使用 PascalCase 定义组件
-
模板中优先使用 PascalCase 标签
-
Props 和事件保持 kebab-case → camelCase 的转换
-
配置文件示例(.eslintrc):
json
{
"vue/component-definition-name-casing": ["error", "PascalCase"],
"vue/component-name-in-template-casing": ["error", "PascalCase"]
}
总结
Vue 3 官方推荐:
-
定义组件时:PascalCase (
UserProfile) -
模板中使用:PascalCase 优先 (
<UserProfile>) -
Props 和事件:定义用 camelCase,使用用 kebab-case
这种约定既利用了 Vue 的自动转换能力,又保持了代码的清晰度和一致性,是 Vue 生态系统中的最佳实践。
遵循这些规则可以显著提高代码的可读性、可维护性和团队协作效率。
在Vue3项目实际开发中,命名规范对于代码的可读性和维护性至关重要。
以下是一个总结表格,涵盖了常见的命名规范,包括组合式函数、组件、变量、常量等。
| 类别 | 命名规则 | 示例 | 说明 |
|---|---|---|---|
| 组合式函数 | 以use开头,camelCase |
useUserStore, useFetch |
表示这是一个可组合的函数,通常用于组合式API。 |
| 组件名(SFC文件) | PascalCase | UserProfile.vue, SideBar.vue |
单文件组件使用大驼峰命名,与组件定义一致。 |
| 组件定义 | PascalCase | UserProfile, SideBar |
在模板中使用的组件名,推荐使用PascalCase,以便与HTML元素区分。 |
| Props定义 | camelCase | userName, isVisible |
在JS/TS中定义props时使用camelCase。 |
| 模板中的Props | kebab-case | user-name, is-visible |
在模板中传递props时,推荐使用kebab-case,因为HTML属性不区分大小写。 |
| 自定义事件 | camelCase(定义),kebab-case(监听) | 定义:update:value,监听:@update:value |
注意:Vue3中推荐使用update:xxx格式的事件名,但实际使用中也可以自定义。在模板中监听时使用kebab-case。 |
| 响应式变量 | camelCase | userData, loading |
使用ref或reactive创建的响应式变量。 |
| 计算属性 | camelCase | fullName, filteredList |
使用computed创建的计算属性。 |
| 函数/方法 | camelCase | handleClick, fetchData |
普通函数和方法命名。 |
| 常量 | UPPER_SNAKE_CASE | MAX_SIZE, API_URL |
全局常量或不会改变的配置值。 |
| 类型定义(TS) | PascalCase | UserProfileProps, User |
TypeScript中的类型和接口。 |
| 枚举 | PascalCase | UserRole, Direction |
枚举类型和枚举值(枚举值通常也使用PascalCase,但有时也使用UPPER_SNAKE_CASE,需统一)。 |
| 自定义指令 | kebab-case | v-focus, v-tooltip |
指令名在模板中使用kebab-case。 |
| 样式类名 | kebab-case | .user-profile, .sidebar |
CSS类名使用小写字母和连字符。 |
| CSS变量 | kebab-case | --primary-color, --header-height |
CSS自定义属性。 |
| 模块导出 | 按导出类型决定 | 变量/函数:camelCase,组件:PascalCase,常量:UPPER_SNAKE_CASE | 根据导出内容的类型采用相应的命名规则。 |
注意:在实际开发中,团队可能会有自己的命名约定,但以上是Vue社区和官方风格指南中常见的规范。保持一致性和可读性是最重要的。
Vue 3 实际开发命名规范总结表
组合式函数 (Composables)
| 类别 | 命名模式 | 强制等级 | 示例 | 说明 |
|---|---|---|---|---|
| 通用组合函数 | use + PascalCase |
强制 | useMouse, useFetch |
标准组合式函数命名 |
| 状态管理 | use + Store名 + Store |
推荐 | useUserStore, useCartStore |
明确表示状态管理 |
| UI相关 | use + UI功能 |
推荐 | useModal, useToast |
UI交互相关 |
| 工具类 | use + 功能 |
推荐 | useLocalStorage, useEventListener |
工具功能封装 |
组件相关
| 类别 | 命名模式 | 强制等级 | 示例 | 说明 |
|---|---|---|---|---|
| 基础组件 | Base + 功能名 |
推荐 | BaseButton.vue, BaseInput.vue |
项目基础组件 |
| 业务组件 | 功能名 + 类型 | 推荐 | UserList.vue, ProductCard.vue |
具体业务功能 |
| 布局组件 | Layout + 位置 |
推荐 | LayoutHeader.vue, LayoutSidebar.vue |
布局相关组件 |
| 页面组件 | 页面名 + Page |
推荐 | HomePage.vue, LoginPage.vue |
路由页面组件 |
| 高阶组件 | with + 功能 |
推荐 | withLoading.vue, withAuth.vue |
增强型组件 |
状态管理 (Pinia)
| 类别 | 命名模式 | 强制等级 | 示例 | 说明 |
|---|---|---|---|---|
| Store定义 | use + 业务 + Store |
推荐 | useUserStore.ts, useProductStore.ts |
Pinia Store命名 |
| State属性 | camelCase | 强制 | userList, totalCount |
状态数据 |
| Getters | 前缀get/is/has |
推荐 | getUserById, isLoggedIn |
计算属性 |
| Actions | 动词开头 | 推荐 | fetchUsers, updateProduct |
操作方法 |
| 常量Action | UPPER_SNAKE | 推荐 | FETCH_USERS, UPDATE_PRODUCT |
Action类型常量 |
TypeScript 类型定义
| 类别 | 命名模式 | 强制等级 | 示例 | 说明 |
|---|---|---|---|---|
| Props接口 | 组件名 + Props |
推荐 | UserCardProps, ModalProps |
组件Props类型 |
| Emit接口 | 组件名 + Emits |
推荐 | UserCardEmits, FormEmits |
组件事件类型 |
| 数据模型 | 业务名 + 类型 | 强制 | User, Product, Order |
数据接口 |
| 请求类型 | 业务名 + Request/Response |
推荐 | LoginRequest, UserResponse |
API请求响应类型 |
| 工具类型 | 功能 + Type |
推荐 | Nullable<T>, PartialBy<T, K> |
工具类型定义 |
API 相关
| 类别 | 命名模式 | 强制等级 | 示例 | 说明 |
|---|---|---|---|---|
| API模块 | api + 业务模块 |
推荐 | userApi.ts, productApi.ts |
API模块文件 |
| 请求函数 | 动词 + 资源名 | 推荐 | getUserList, createOrder |
API函数命名 |
| API常量 | UPPER_SNAKE | 推荐 | API_BASE_URL, REQUEST_TIMEOUT |
API配置常量 |
| 请求拦截器 | 前缀request/response |
推荐 | requestInterceptor, responseInterceptor |
拦截器函数 |
工具函数
| 类别 | 命名模式 | 强制等级 | 示例 | 说明 |
|---|---|---|---|---|
| 通用工具 | 动词 + 名词 | 推荐 | formatDate, deepClone |
通用功能函数 |
| 验证函数 | 前缀validate/is |
推荐 | validateEmail, isPhoneNumber |
验证相关函数 |
| 格式化函数 | 前缀format |
推荐 | formatCurrency, formatFileSize |
格式化函数 |
| 业务工具 | 业务名 + 功能 | 推荐 | userHelper.ts, orderUtils.ts |
业务特定工具 |
常量定义
| 类别 | 命名模式 | 强制等级 | 示例 | 说明 |
|---|---|---|---|---|
| 配置常量 | UPPER_SNAKE | 强制 | APP_NAME, MAX_UPLOAD_SIZE |
应用配置 |
| 路由常量 | UPPER_SNAKE | 推荐 | ROUTE_HOME, ROUTE_LOGIN |
路由名称常量 |
| 状态码 | 前缀STATUS_ |
推荐 | STATUS_SUCCESS, STATUS_ERROR |
状态码常量 |
| 枚举值 | UPPER_SNAKE | 推荐 | USER_ROLE_ADMIN, ORDER_STATUS_PAID |
枚举常量 |
样式与类名
| 类别 | 命名模式 | 强制等级 | 示例 | 说明 |
|---|---|---|---|---|
| BEM命名 | block__element--modifier | 推荐 | .user-card__avatar--large |
BEM命名规范 |
| 作用域类 | 组件名 + 元素 | 推荐 | .user-profile-avatar |
Scoped样式 |
| 工具类 | 前缀u-/t- |
推荐 | .u-text-center, .t-primary |
工具类/主题类 |
| 状态类 | 前缀is-/has- |
推荐 | .is-active, .has-error |
状态类名 |
文件与目录
| 类别 | 命名模式 | 强制等级 | 示例 | 说明 |
|---|---|---|---|---|
| 组件目录 | 复数形式 | 推荐 | components/, views/ |
目录命名 |
| 工具目录 | 复数形式 | 推荐 | utils/, composables/ |
工具目录 |
| 测试文件 | 组件名 + .spec |
强制 | UserCard.spec.ts, useFetch.spec.ts |
测试文件命名 |
| 配置文件 | 前缀. + 工具名 |
推荐 | .eslintrc, .prettierrc |
配置文件 |
钩子函数 (Lifecycle)
| 类别 | 命名模式 | 强制等级 | 示例 | 说明 |
|---|---|---|---|---|
| 生命周期 | on + 事件名 | 强制 | onMounted, onUpdated |
Composition API钩子 |
| 自定义钩子 | on + 事件 | 推荐 | onRouteChange, onResize |
自定义生命周期 |
响应式变量命名约定
| 类别 | 命名模式 | 强制等级 | 示例 | 说明 |
|---|---|---|---|---|
| ref变量 | 名词 + Ref |
推荐 | userRef, inputRef |
模板ref引用 |
| 响应式对象 | 业务名 + Data |
推荐 | userData, formData |
reactive对象 |
| 计算属性 | 描述性名词 | 推荐 | fullName, totalPrice |
computed值 |
| 异步状态 | 名词 + 状态 | 推荐 | userLoading, submitPending |
加载状态 |
事件处理函数
| 类别 | 命名模式 | 强制等级 | 示例 | 说明 |
|---|---|---|---|---|
| 点击事件 | handle + 元素 + Click |
推荐 | handleButtonClick, handleSubmitClick |
点击处理 |
| 输入事件 | handle + 输入 + Change |
推荐 | handleInputChange, handleSelectChange |
输入处理 |
| 表单事件 | handle + Form + Submit |
推荐 | handleFormSubmit, handleLoginSubmit |
表单提交 |
| 自定义事件 | 前缀on |
推荐 | onUserSelect, onProductUpdate |
自定义回调 |
实用命名模式速查表
| 模式 | 用途 | 示例 |
|---|---|---|
useXxx |
组合式函数 | useFetch, useLocalStorage |
XxxStore |
状态管理 | UserStore, CartStore |
BaseXxx |
基础组件 | BaseButton, BaseInput |
XxxProps |
Props类型 | UserCardProps, ModalProps |
getXxx |
获取函数 | getUserInfo, getProductList |
setXxx |
设置函数 | setUserInfo, setTheme |
isXxx |
布尔判断 | isLoading, isValid |
hasXxx |
存在判断 | hasError, hasPermission |
formatXxx |
格式化 | formatDate, formatPrice |
validateXxx |
验证 | validateEmail, validateForm |
handleXxx |
事件处理 | handleClick, handleSubmit |
onXxx |
回调/钩子 | onSuccess, onMounted |
XxxRequest |
请求类型 | LoginRequest, UpdateRequest |
XxxResponse |
响应类型 | UserResponse, OrderResponse |
大小写规则总结
| 语法结构 | 大小写规则 | 示例 |
|---|---|---|
| 文件名 | PascalCase (组件) / camelCase (工具) | UserCard.vue, formatDate.ts |
| 变量/函数 | camelCase | userName, getUserInfo() |
| 类/类型/接口 | PascalCase | User, ProductProps |
| 常量 | UPPER_SNAKE_CASE | API_BASE_URL, MAX_SIZE |
| 组件标签 | PascalCase (推荐) | <UserCard>, <BaseButton> |
| HTML属性 | kebab-case | user-name, is-active |
| CSS类名 | kebab-case | .user-card, .is-active |
| 枚举值 | PascalCase 或 UPPER_SNAKE | Admin, USER_ROLE_ADMIN |
最佳实践建议
-
保持一致性:团队内部统一命名规范
-
语义化命名:名称应清晰表达用途
-
避免缩写:除非是广泛接受的缩写(如API、HTTP)
-
文件组织:按功能模块组织文件结构
-
类型安全:充分利用TypeScript类型提示
-
文档注释:复杂函数和组件添加JSDoc注释
这些规范在实际项目中可以帮助团队保持代码一致性,提高代码可读性和可维护性。