跳转到内容

命名规范与代码风格指南

本文档定义了项目中Vue 3应用和文档的命名规范、代码风格以及最佳实践,确保团队协作的一致性和代码可维护性。

文件和目录命名

页面和视图文件

使用 kebab-case(短横线命名法),保持路径一致性,确保跨平台兼容性。

text
src/views/
  user-profile/
    index.vue
  settings-page.vue
  order-list.vue

组件文件

使用 PascalCase(大驼峰命名法),与组件名称保持一致。

text
src/components/
  UserProfile.vue
  SettingsForm.vue
  OrderTable.vue

Composables文件

使用 camelCase(小驼峰命名法),以 use 开头。

text
src/composables/  或 src/hooks/
  usePagination.js
  useUserAuth.js
  useFormData.js

工具函数文件

使用 camelCase

text
src/utils/
  dateUtils.js
  request.js
  validation.js

目录命名

使用 kebab-case

text
src/
  api/
  assets/
  components/
  composables/
  directives/
  router/
  store/
  utils/
  views/

组件命名

组件名称规则

单文件组件(SFC)

使用 PascalCase,文件名与组件注册名保持一致。

vue
<!-- UserProfile.vue -->
<script setup>
defineOptions({
  name: 'UserProfile'
})
</script>

组件注册

在模板中使用 kebab-case,在JavaScript中使用 PascalCase

vue
<template>
  <!-- 模板中使用 kebab-case -->
  <user-profile />
  <settings-form />
</template>

<script setup>
// JavaScript 中使用 PascalCase
import UserProfile from '@/components/UserProfile.vue'
import SettingsForm from '@/components/SettingsForm.vue'
</script>

基础组件命名

对于通用基础组件,以 Base 开头,便于在IDE中快速查找和识别。

text
BaseButton.vue
BaseInput.vue
BaseModal.vue
BaseTable.vue

单例组件命名

对于全局只有一个实例的组件,以 The 开头。

text
TheHeader.vue
TheFooter.vue
TheSidebar.vue

紧密耦合组件命名

对于父子关系紧密的组件,使用父组件名作为前缀。

text
TodoList.vue
TodoListItem.vue
TodoListButton.vue

变量和常量命名

基本规则

使用 camelCase(小驼峰),命名要有语义,可读性强。

javascript
// 正确
const userName = 'John'
const isLoading = false
const totalAmount = 100

// 错误
const x = 'John'
const flag = false
const num = 100

布尔值命名

使用 ishascanshould 等前缀,清晰表示布尔语义。

javascript
// 状态相关
const isLoading = true
const isActive = false
const isVisible = true
const isDisabled = false

// 拥有关系
const hasPermission = true
const hasError = false
const hasData = true

// 能力相关
const canEdit = true
const canDelete = false
const canSubmit = true

// 建议相关
const shouldUpdate = true
const shouldRefresh = false

常量命名

使用 UPPER_SNAKE_CASE(全大写下划线分隔)。

javascript
// API配置
const API_BASE_URL = 'https://api.example.com'
const MAX_RETRY_COUNT = 3
const DEFAULT_PAGE_SIZE = 10

// 状态码
const HTTP_STATUS_OK = 200
const HTTP_STATUS_NOT_FOUND = 404

// 时间相关
const CACHE_EXPIRE_TIME = 3600000
const REQUEST_TIMEOUT = 5000

特殊数据类型命名

对于特定数据结构,使用语义化前缀。

javascript
// 列表数据
const userList = []
const orderList = []
const fileList = []

// 对象数据
const userObject = {}
const configObject = {}

// 选择器数据
const cityPicker = []
const dateSelector = null

// 搜索相关
const searchKeyword = ''
const searchResult = []
const searchFilters = {}

Vue 3响应式数据命名

使用 ref()reactive() 时,遵循Vue 3最佳实践。

javascript
// ref - 用于基本类型和需要整体替换的对象
const count = ref(0)
const user = ref(null)
const loading = ref(false)

// reactive - 用于不需要整体替换的对象
const form = reactive({
  username: '',
  password: ''
})

const pagination = reactive({
  page: 1,
  pageSize: 10,
  total: 0
})

函数和方法命名

基本规则

使用 camelCase,函数名应该是动词或动词短语,清晰表达函数的作用。

事件处理函数

使用 handle 前缀,表示这是对某个事件的响应。

javascript
// 点击事件
function handleClick() {}
function handleButtonClick() {}
function handleItemClick() {}

// 表单事件
function handleSubmit() {}
function handleChange() {}
function handleInput() {}

// 生命周期
function handleMount() {}
function handleUpdate() {}

数据获取函数

使用 fetchload 前缀。

javascript
// 获取数据
async function fetchUserList() {}
async function loadUserInfo() {}
async function fetchOrderDetail() {}

// 刷新数据
async function refreshData() {}
async function reloadPage() {}

状态修改函数

使用 setupdatetoggle 等动词。

javascript
// 设置值
function setUserName(name) {}
function setUserAge(age) {}

// 更新状态
function updateUserList(list) {}
function updateFormData(data) {}

// 切换状态
function toggleLoading() {}
function toggleSidebar() {}
function switchTab() {}

数据操作函数

javascript
// 添加
function addUser(user) {}
function addItem(item) {}
function createOrder(order) {}

// 删除
function deleteUser(id) {}
function removeItem(index) {}
function clearList() {}

// 验证
function validateForm(data) {}
function checkPermission(user) {}
function verifyCode(code) {}

工具函数

使用描述性的名称,清晰表达输入和输出的关系。

javascript
// 格式化
function formatDate(date) {}
function formatNumber(num) {}
function formatCurrency(amount) {}

// 转换
function toString(value) {}
function toArray(value) {}
function toJson(data) {}

// 计算
function calculateTotal(items) {}
function computeDiscount(price) {}
function getCount(list) {}

事件命名

自定义事件(Emits)

使用 kebab-case,在模板中绑定事件时使用 kebab-case

vue
<script setup>
// 定义事件(使用 camelCase)
const emit = defineEmits(['update:modelValue', 'item-click', 'data-change'])

// 触发事件
function handleClick() {
  emit('item-click', { id: 1 })
  emit('update:modelValue', newValue)
}
</script>

<template>
  <!-- 监听事件时使用 kebab-case -->
  <child-component @item-click="handleItemClick" />
</template>

事件命名建议

javascript
// 更新事件
'update:modelValue'
'update:username'
'update:status'

// 交互事件
'item-click'
'button-press'
'form-submit'

// 状态变化事件
'loading-change'
'status-update'
'data-loaded'

CSS和样式命名

使用BEM命名规范

BEM(Block Element Modifier)是一种清晰的CSS命名方法论。

css
/* Block(块)*/
.user-card { }
.button { }

/* Element(元素)*/
.user-card__header { }
.user-card__body { }
.user-card__footer { }
.button__icon { }

/* Modifier(修饰符)*/
.user-card--active { }
.user-card--disabled { }
.button--primary { }
.button--large { }

Vue Scoped样式

在Vue组件中,优先使用 scoped 样式,避免样式污染。

vue
<template>
  <div class="user-list">
    <div class="user-list__item">用户1</div>
    <div class="user-list__item user-list__item--active">用户2</div>
  </div>
</template>

<style scoped>
.user-list {
  padding: 20px;
}

.user-list__item {
  margin-bottom: 10px;
}

.user-list__item--active {
  color: #409eff;
}
</style>

动态类名绑定

使用计算属性或对象语法处理动态类名。

vue
<template>
  <div
    :class="['user-card', cardClass, { 'user-card--active': isActive }]"
  >
    内容
  </div>
</template>

<script setup>
const props = defineProps({
  type: String
})

const isActive = computed(() => props.type === 'active')
const cardClass = computed(() => `user-card--${props.type}`)
</script>

代码注释规范

文件头注释

Vue单文件组件应该包含文件头注释。

vue
<!--
  @description 用户列表页面组件
  @author 作者名
  @date 2025-01-15
-->
<template>
  <div class="user-list">
    <!-- 页面内容 -->
  </div>
</template>

函数注释

对于复杂函数,使用JSDoc风格的注释。

javascript
/**
 * 获取用户列表数据
 * @param {Object} params - 查询参数
 * @param {number} params.page - 页码
 * @param {number} params.pageSize - 每页条数
 * @param {string} params.keyword - 搜索关键词
 * @returns {Promise<Object>} 返回用户列表数据
 * @throws {Error} 网络请求失败时抛出错误
 */
async function fetchUserList(params) {
  const { page, pageSize, keyword } = params
  // 实现代码
}

单行注释

对于简单的逻辑,使用单行注释。

javascript
// 检查用户是否登录
if (isLoggedIn) {
  // 执行登录后的操作
}

// 格式化日期显示
const formattedDate = formatDate(new Date())

逻辑块注释

对于复杂的逻辑块,使用注释分隔。

javascript
function processUserData() {
  // 第一步:获取原始数据
  const rawData = fetchRawData()

  // 第二步:过滤无效数据
  const filteredData = rawData.filter(item => item.isValid)

  // 第三步:格式化数据
  const formattedData = filteredData.map(formatItem)

  // 第四步:返回处理结果
  return formattedData
}

TODO注释

使用TODO标记待完成的功能。

javascript
// TODO: 添加分页功能
// TODO: 优化性能,考虑使用虚拟滚动
// FIXME: 修复在快速点击时的状态异常

代码风格配置

项目使用 Prettier 进行代码格式化,配置文件 .prettierrc.js

javascript
export default {
  // 每行最大字符数
  printWidth: 150,

  // 缩进空格数
  tabWidth: 2,

  // 使用制表符缩进
  useTabs: true,

  // 语句末尾添加分号
  semi: true,

  // 使用单引号
  singleQuote: true,

  // 对象属性引号规则:仅在需要时添加
  quoteProps: 'as-needed',

  // JSX中使用单引号
  jsxSingleQuote: false,

  // 多行时添加尾随逗号(ES5标准)
  trailingComma: 'es5',

  // 对象括号间添加空格
  bracketSpacing: true,

  // JSX括号换行
  jsxBracketSameLine: false,

  // 箭头函数参数括号
  arrowParens: 'always',

  // 换行符类型
  endOfLine: 'lf'
}

VS Code配置

项目根目录的 .vscode/settings.json 配置:

json
{
  "editor.formatOnSave": true,
  "editor.defaultFormatter": "esbenp.prettier-vscode",
  "editor.tabSize": 2,
  "editor.insertSpaces": false,
  "files.eol": "\n"
}

Git提交规范

项目使用 Husky + Commitlint 强制执行提交消息规范。

提交消息格式

<type>(<scope>): <subject>

类型(type)

类型说明示例
feat新增功能feat: 新增用户管理模块
fix修复Bugfix: 修复登录验证逻辑错误
docs文档或注释变更docs: 补充API文档和注释
style代码格式调整(不影响功能)style: 格式化代码缩进
refactor代码重构(不是新功能也不是修复)refactor: 重构用户列表组件
perf性能优化perf: 优化表格渲染性能
test测试相关test: 添加用户单元测试
build构建系统或外部依赖变更build: 升级Vite到6.0
ciCI配置文件和脚本变更ci: 更新GitHub Actions配置
chore其他不修改src或测试文件的变更chore: 更新.gitignore
revert回退之前的提交revert: feat(用户管理)
update更新模块或调整功能逻辑update: 更新订单列表筛选逻辑

范围(scope)

范围用于指定提交影响的模块,例如:

feat(user): 新增用户登录功能
fix(order): 修复订单列表分页错误
docs(api): 更新API接口文档

主题(subject)

主题描述应该:

  • 使用现在时态("change" 而非 "changed" 或 "changes")
  • 首字母小写
  • 不要以句号结尾

完整示例

bash
# 新增功能
git commit -m "feat(user): 新增用户注册功能"

# 修复Bug
git commit -m "fix: 修复列表快速切换分页时的报错"

# 更新文档
git commit -m "docs: 补充组件使用示例"

# 重构
git commit -m "refactor(auth): 重构登录验证逻辑"

# 性能优化
git commit -m "perf: 优化用户列表渲染性能"

常用术语表

页面和路由相关

单词含义用途
home首页网站主页
login登录用户登录页面
logout登出用户退出登录
register注册用户注册页面
profile个人资料用户个人信息
settings设置用户设置页面
dashboard仪表盘数据概览页面
detail详情详情页面
list列表列表页面
form表单表单页面
search搜索搜索页面
about关于关于页面
contact联系我们联系页面
error错误页错误页面
not-found404页面页面未找到

状态和属性

单词含义用途
is是否状态前缀
has是否拥有拥有关系
can能否权限检查
should是否应该建议性状态
enabled启用功能启用
disabled禁用功能禁用
active激活激活状态
inactive未激活非激活状态
loading加载中加载状态
pending待处理等待状态
success成功成功状态
failed失败失败状态
visible可见显示状态
hidden隐藏隐藏状态
expanded展开展开状态
collapsed收起收起状态

UI组件

单词含义用途
header头部页面头部
footer底部页面底部
sidebar侧边栏侧边导航
navbar导航栏导航栏
menu菜单菜单组件
dropdown下拉菜单下拉选择
button按钮按钮组件
input输入框输入组件
select选择框选择组件
checkbox复选框多选框
radio单选框单选框
switch开关开关组件
slider滑块滑动选择
modal弹窗模态框
dialog对话框对话框
tooltip提示框提示组件
table表格表格组件
card卡片卡片组件
tag标签标签组件
badge徽章徽章组件
pagination分页分页组件
breadcrumb面包屑面包屑导航
tabs标签页标签页组件

数据操作

单词含义用途
get获取获取数据
set设置设置值
fetch拉取API请求
load加载加载数据
update更新更新数据
delete删除删除数据
remove移除移除数据
create创建创建数据
add添加添加数据
edit编辑编辑操作
save保存保存操作
submit提交提交表单
validate校验数据验证
reset重置重置状态
clear清空清空数据
init初始化初始化操作
open打开打开操作
close关闭关闭操作
toggle切换切换状态
render渲染渲染数据

数据类型

单词含义用途
data数据通用数据
item项目单个项目
items项目列表项目集合
value数据值
values值集合多个值
key键名
keys键集合多个键
id唯一标识ID
idsID集合多个ID
name名称名称
title标题标题
label标签标签文本
content内容内容
description描述描述信息
type类型数据类型
status状态状态值
state状态状态对象
config配置配置对象
options选项可选项
params参数参数对象
query查询参数查询字符串
result结果结果对象
results结果集多个结果
response响应API响应
request请求API请求

功能模块

单词含义用途
auth授权认证授权
token令牌访问令牌
session会话用户会话
cache缓存缓存数据
storage存储本地存储
redirect跳转页面跳转
router路由路由配置
route路由单个路由
store仓库状态存储
state状态应用状态
getter获取器状态获取
action动作状态操作
mutation变更状态变更
module模块功能模块
feature功能特性功能
plugin插件插件系统
service服务服务层
api接口API接口
mock模拟数据Mock数据
test测试测试代码
spec规范测试规范
build构建构建工具
deploy部署部署流程
env环境环境变量

辅助工具

单词含义用途
utils工具工具函数
helper帮助类辅助类
common通用通用模块
constants常量常量定义
config配置配置文件
settings设置设置文件
theme主题主题配置
style样式样式文件
styles样式集合多个样式
assets资源资源文件
images图片图片资源
icons图标图标资源
fonts字体字体文件
vendor第三方库第三方库
core核心核心模块
base基础基础模块
shared共享共享模块

用户和角色

单词含义用途
user用户用户对象
users用户列表多个用户
admin管理员管理员
guest访客访客用户
member成员成员用户
role角色用户角色
roles角色列表多个角色
permission权限权限设置
permissions权限列表多个权限

错误和日志

单词含义用途
error错误错误信息
errors错误集合多个错误
warning警告警告信息
message消息提示消息
messages消息集合多个消息
notification通知通知消息
log日志日志记录
logger日志器日志工具

Vue 3特殊规范

Composition API命名

Composables命名

使用 use 前缀,返回对象中包含响应式状态和方法。

javascript
// usePagination.js
import { ref, computed } from 'vue'

export function usePagination(apiFunc) {
  const loading = ref(false)
  const dataList = ref([])
  const pagination = reactive({
    page: 1,
    pageSize: 10,
    total: 0
  })

  async function loadData() {
    loading.value = true
    try {
      const res = await apiFunc({
        page: pagination.page,
        pageSize: pagination.pageSize
      })
      dataList.value = res.list
      pagination.total = res.total
    } finally {
      loading.value = false
    }
  }

  return {
    loading,
    dataList,
    pagination,
    loadData
  }
}

生命周期函数命名

使用 on 前缀,清晰表达生命周期钩子。

javascript
import { onMounted, onUnmounted } from 'vue'

onMounted(() => {
  // 组件挂载后的操作
})

onUnmounted(() => {
  // 组件卸载前的清理操作
})

Props和Emits命名

Props定义

使用 TypeScript 类型定义,属性名使用 camelCase

vue
<script setup>
interface Props {
  userName: string
  isActive?: boolean
  userId: number
}

// 使用 withDefaults 设置默认值
const props = withDefaults(defineProps<Props>(), {
  isActive: false
})
</script>

Emits定义

事件名使用 kebab-case,但 defineEmits 中使用 camelCase

vue
<script setup>
interface Emits {
  'update:modelValue': [value: string]
  'item-click': [item: Item]
  'data-change': [data: Data, options?: Options]
}

const emit = defineEmits<Emits>()

// 触发事件
function handleClick(item) {
  emit('item-click', item)
}
</script>

Ref和Reactive命名

javascript
// ref - 用于基本类型和需要整体替换的对象
const count = ref(0)
const user = ref<User | null>(null)
const error = ref<string>('')

// reactive - 用于深层对象
const form = reactive<FormData>({
  username: '',
  password: ''
})

// computed - 计算属性,使用动词过去式
const filteredList = computed(() =>
  list.value.filter(item => item.active)
)

const isValid = computed(() =>
  form.username && form.password
)

Watch和WatchEffect命名

javascript
// watch - 监听特定源
watch(
  () => props.userId,
  (newId, oldId) => {
    console.log(`用户ID从${oldId}变为${newId}`)
  }
)

// watchEffect - 自动追踪依赖
watchEffect(() => {
  console.log(`当前用户:${user.value?.name}`)
})

最佳实践总结

通用原则

  1. 语义化优先:名称应该清晰表达其用途,避免缩写(除非是广泛认知的缩写)
  2. 一致性:整个项目中保持命名风格一致
  3. 可读性:名称应该易于阅读和理解
  4. 避免过载:不要使用语言保留字和内置函数名
  5. 简洁明确:在保证清晰的前提下,尽量简短

Vue 3特定建议

  1. 组件命名:使用 PascalCase,与文件名保持一致
  2. 事件命名:使用 kebab-case,遵循 Vue 3 约定
  3. Composables命名:使用 use 前缀
  4. 响应式数据:根据场景选择 refreactive
  5. 类型安全:使用 TypeScript 定义 Props、Emits 和数据类型

Will Try My Best.