Skip to content

代码规范

统一的代码规范有助于提高代码质量和团队协作效率。

命名规范

后端命名规范

包名

  • 全小写
  • 使用点分隔
  • 避免使用下划线或连字符
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

相关链接

MIT License