代码规范
统一的代码规范有助于提高代码质量和团队协作效率。
命名规范
后端命名规范
包名
- 全小写
- 使用点分隔
- 避免使用下划线或连字符
java
// ✅ 正确
package com.vben.system.controller;
package com.vben.common.utils;
// ❌ 错误
package com.vben.System.Controller;
package com.vben.common_utils;类名
- 大驼峰(PascalCase)
- 名词或名词短语
- 见名知意
java
// ✅ 正确
public class UserController {}
public class UserServiceImpl {}
public class ExcelUtils {}
// ❌ 错误
public class user {}
public class UserCon {}
public class Utils {}方法名
- 小驼峰(camelCase)
- 动词或动词短语
- 布尔方法以 is/has/can 开头
java
// ✅ 正确
public void saveUser() {}
public User getUserById(Long id) {}
public boolean isAdmin() {}
public boolean hasPermission() {}
// ❌ 错误
public void Save() {}
public User get_user() {}
public boolean admin() {}变量名
- 小驼峰(camelCase)
- 名词或名词短语
- 避免单字母变量(除循环变量)
java
// ✅ 正确
String userName = "张三";
int userAge = 25;
List<User> userList = new ArrayList<>();
// ❌ 错误
String s = "张三";
int a = 25;
List<User> list = new ArrayList<>();常量名
- 全大写
- 使用下划线分隔
- static final 修饰
java
// ✅ 正确
public static final int MAX_SIZE = 100;
public static final String DEFAULT_NAME = "默认";
// ❌ 错误
public static final int maxSize = 100;
public static final String defaultName = "默认";前端命名规范
文件名
- kebab-case(短横线分隔)
- 小写字母
- 见名知意
✅ 正确
user-list.vue
user-detail.vue
export-utils.ts
❌ 错误
UserList.vue
userDetail.vue
ExportUtils.ts组件名
- PascalCase(大驼峰)
- 多个单词组成
- 避免单词缩写
vue
<!-- ✅ 正确 -->
<script setup lang="ts">
import UserList from './user-list.vue'
import UserDetail from './user-detail.vue'
</script>
<!-- ❌ 错误 -->
<script setup lang="ts">
import userList from './userList.vue'
import UsrDtl from './usr-dtl.vue'
</script>变量名
- camelCase(小驼峰)
- 名词或名词短语
- 布尔变量以 is/has/can 开头
typescript
// ✅ 正确
const userName = ref('张三')
const userAge = ref(25)
const isLoading = ref(false)
const hasPermission = ref(true)
// ❌ 错误
const UserName = ref('张三')
const user_age = ref(25)
const loading = ref(false)函数名
- camelCase(小驼峰)
- 动词或动词短语
- 事件处理函数以 handle 开头
typescript
// ✅ 正确
function getUserList() {}
function handleClick() {}
function handleSubmit() {}
// ❌ 错误
function GetUserList() {}
function click() {}
function submit() {}常量名
- UPPER_CASE(全大写)
- 使用下划线分隔
typescript
// ✅ 正确
const MAX_SIZE = 100
const DEFAULT_PAGE_SIZE = 10
const API_BASE_URL = 'https://api.example.com'
// ❌ 错误
const maxSize = 100
const defaultPageSize = 10
const apiBaseUrl = 'https://api.example.com'代码格式
后端代码格式
缩进
- 使用 4 个空格缩进
- 不使用 Tab
java
// ✅ 正确
public class User {
private Long id;
private String name;
public void save() {
if (id != null) {
update();
} else {
insert();
}
}
}大括号
- 左大括号不换行
- 右大括号换行
- if/else/for/while 必须使用大括号
java
// ✅ 正确
if (condition) {
doSomething();
} else {
doOtherThing();
}
// ❌ 错误
if (condition)
{
doSomething();
}
if (condition) doSomething();空格
- 运算符两侧加空格
- 逗号后加空格
- 关键字后加空格
java
// ✅ 正确
int result = a + b;
List<String> list = Arrays.asList("a", "b", "c");
if (condition) {}
// ❌ 错误
int result=a+b;
List<String> list=Arrays.asList("a","b","c");
if(condition){}空行
- 方法之间空一行
- 逻辑块之间空一行
- 类成员变量和方法之间空一行
java
// ✅ 正确
public class User {
private Long id;
private String name;
public void save() {
validate();
if (id != null) {
update();
} else {
insert();
}
}
public void delete() {
// ...
}
}前端代码格式
缩进
- 使用 2 个空格缩进
- 不使用 Tab
vue
<!-- ✅ 正确 -->
<template>
<div class="container">
<h1>标题</h1>
<p>内容</p>
</div>
</template>
<script setup lang="ts">
const handleClick = () => {
if (condition) {
doSomething()
}
}
</script>引号
- 优先使用单引号
- 模板字符串使用反引号
typescript
// ✅ 正确
const name = 'Zhang San'
const message = `Hello, ${name}`
// ❌ 错误
const name = "Zhang San"
const message = 'Hello, ' + name分号
- 语句末尾不加分号(可选)
- 保持一致性
typescript
// ✅ 正确(不使用分号)
const name = 'Zhang San'
const age = 25
// ✅ 正确(使用分号)
const name = 'Zhang San';
const age = 25;
// ❌ 错误(不一致)
const name = 'Zhang San';
const age = 25对象和数组
- 多行时每项占一行
- 最后一项加逗号
typescript
// ✅ 正确
const user = {
name: 'Zhang San',
age: 25,
email: 'zhangsan@example.com',
}
const list = [
'item1',
'item2',
'item3',
]
// ❌ 错误
const user = { name: 'Zhang San', age: 25, email: 'zhangsan@example.com' }
const list = ['item1', 'item2', 'item3']注释规范
后端注释
类注释
java
/**
* 用户服务实现类
*
* @author Zhang San
* @since 2026-02-05
*/
@Service
public class UserServiceImpl implements UserService {
// ...
}方法注释
java
/**
* 根据用户名获取用户信息
*
* @param username 用户名
* @return 用户信息,不存在返回 null
*/
public User getUserByUsername(String username) {
return lambdaQuery()
.eq(User::getUsername, username)
.one();
}字段注释
java
public class User {
/** 用户 ID */
private Long id;
/** 用户名 */
private String username;
/** 用户状态:0-禁用,1-启用 */
private Integer status;
}前端注释
函数注释
typescript
/**
* 获取用户列表
* @param params 查询参数
* @returns 用户列表
*/
export function getUserList(params?: UserListParams) {
return request.get<UserListResult>('/api/system/user/list', { params })
}复杂逻辑注释
typescript
// 计算用户权限
// 1. 获取用户角色
// 2. 获取角色权限
// 3. 合并去重
const permissions = computed(() => {
const roles = userStore.roles
const perms = roles.flatMap(role => role.permissions)
return [...new Set(perms)]
})TODO 注释
typescript
// TODO: 优化性能
// FIXME: 修复 Bug
// HACK: 临时方案
// NOTE: 重要说明最佳实践
后端最佳实践
使用 Lombok
java
// ✅ 正确
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class User {
private Long id;
private String username;
}
// ❌ 错误(手写 getter/setter)
public class User {
private Long id;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
}使用 Lambda 查询
java
// ✅ 正确
List<User> users = userService.lambdaQuery()
.eq(User::getStatus, 1)
.like(User::getUsername, keyword)
.list();
// ❌ 错误
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.eq("status", 1);
wrapper.like("username", keyword);
List<User> users = userService.list(wrapper);异常处理
java
// ✅ 正确
try {
doSomething();
} catch (BusinessException e) {
log.error("业务异常:{}", e.getMessage());
throw e;
} catch (Exception e) {
log.error("系统异常", e);
throw new BusinessException("操作失败");
}
// ❌ 错误
try {
doSomething();
} catch (Exception e) {
e.printStackTrace();
}前端最佳实践
使用 Composition API
vue
<!-- ✅ 正确 -->
<script setup lang="ts">
import { ref, computed, onMounted } from 'vue'
const count = ref(0)
const doubleCount = computed(() => count.value * 2)
onMounted(() => {
console.log('mounted')
})
</script>
<!-- ❌ 错误(Options API) -->
<script lang="ts">
export default {
data() {
return {
count: 0
}
},
computed: {
doubleCount() {
return this.count * 2
}
},
mounted() {
console.log('mounted')
}
}
</script>类型定义
typescript
// ✅ 正确
interface User {
id: number
username: string
email: string
}
const user = ref<User>({
id: 1,
username: 'zhangsan',
email: 'zhangsan@example.com'
})
// ❌ 错误
const user = ref({
id: 1,
username: 'zhangsan',
email: 'zhangsan@example.com'
})组件拆分
vue
<!-- ✅ 正确 -->
<script setup lang="ts">
import UserTable from './components/user-table.vue'
import UserForm from './components/user-form.vue'
</script>
<template>
<div class="user-page">
<UserTable />
<UserForm />
</div>
</template>
<!-- ❌ 错误(所有代码在一个文件) -->
<script setup lang="ts">
// 500+ 行代码
</script>
<template>
<!-- 复杂的模板 -->
</template>工具配置
ESLint 配置
javascript
// .eslintrc.js
module.exports = {
extends: [
'plugin:vue/vue3-recommended',
'@vue/typescript/recommended',
'prettier'
],
rules: {
'vue/multi-word-component-names': 'off',
'@typescript-eslint/no-explicit-any': 'warn',
'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
}
}Prettier 配置
javascript
// .prettierrc.js
module.exports = {
semi: false,
singleQuote: true,
printWidth: 100,
trailingComma: 'es5',
arrowParens: 'always',
}EditorConfig 配置
ini
# .editorconfig
root = true
[*]
charset = utf-8
indent_style = space
indent_size = 2
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
[*.java]
indent_size = 4
[*.md]
trim_trailing_whitespace = false