|
|
# 代码规范文档
|
|
|
|
|
|
## 📋 文档信息
|
|
|
|
|
|
- **文档版本**: v1.0.0
|
|
|
- **创建日期**: 2024年
|
|
|
- **最后更新**: 2024年
|
|
|
- **文档状态**: 草稿
|
|
|
- **维护人员**: 开发团队
|
|
|
|
|
|
## 🎯 代码规范概述
|
|
|
|
|
|
本规范旨在统一团队代码风格,提高代码质量,确保代码的可读性和可维护性。
|
|
|
|
|
|
## 📝 命名规范
|
|
|
|
|
|
### 文件命名
|
|
|
- **Vue 组件**: 使用 PascalCase,如 `UserProfile.vue`
|
|
|
- **JavaScript 文件**: 使用 camelCase,如 `userService.js`
|
|
|
- **CSS/SCSS 文件**: 使用 kebab-case,如 `user-profile.scss`
|
|
|
- **常量文件**: 使用 UPPER_SNAKE_CASE,如 `API_ENDPOINTS.js`
|
|
|
|
|
|
### 变量命名
|
|
|
```javascript
|
|
|
// 使用 camelCase
|
|
|
const userName = 'John';
|
|
|
const isActive = true;
|
|
|
const userList = [];
|
|
|
|
|
|
// 常量使用 UPPER_SNAKE_CASE
|
|
|
const API_BASE_URL = 'https://api.example.com';
|
|
|
const MAX_RETRY_COUNT = 3;
|
|
|
```
|
|
|
|
|
|
### 函数命名
|
|
|
```javascript
|
|
|
// 使用 camelCase,动词开头
|
|
|
function getUserInfo() { }
|
|
|
function updateUserProfile() { }
|
|
|
function validateEmail() { }
|
|
|
|
|
|
// 布尔值函数使用 is/has/can 开头
|
|
|
function isValidUser() { }
|
|
|
function hasPermission() { }
|
|
|
function canEdit() { }
|
|
|
```
|
|
|
|
|
|
### 组件命名
|
|
|
```vue
|
|
|
<!-- 组件名使用 PascalCase -->
|
|
|
<template>
|
|
|
<div class="user-profile">
|
|
|
<UserAvatar />
|
|
|
<UserInfo />
|
|
|
</div>
|
|
|
</template>
|
|
|
|
|
|
<script>
|
|
|
export default {
|
|
|
name: 'UserProfile',
|
|
|
components: {
|
|
|
UserAvatar,
|
|
|
UserInfo
|
|
|
}
|
|
|
}
|
|
|
</script>
|
|
|
```
|
|
|
|
|
|
## 🏗️ Vue 组件规范
|
|
|
|
|
|
### 组件结构
|
|
|
```vue
|
|
|
<template>
|
|
|
<!-- 模板内容 -->
|
|
|
</template>
|
|
|
|
|
|
<script>
|
|
|
// 导入语句
|
|
|
import { mapState, mapActions } from 'vuex'
|
|
|
import UserService from '@/api/user'
|
|
|
|
|
|
// 组件定义
|
|
|
export default {
|
|
|
name: 'ComponentName',
|
|
|
components: {
|
|
|
// 组件注册
|
|
|
},
|
|
|
props: {
|
|
|
// 属性定义
|
|
|
},
|
|
|
data() {
|
|
|
return {
|
|
|
// 数据定义
|
|
|
}
|
|
|
},
|
|
|
computed: {
|
|
|
// 计算属性
|
|
|
},
|
|
|
watch: {
|
|
|
// 监听器
|
|
|
},
|
|
|
created() {
|
|
|
// 生命周期钩子
|
|
|
},
|
|
|
methods: {
|
|
|
// 方法定义
|
|
|
}
|
|
|
}
|
|
|
</script>
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
|
/* 样式定义 */
|
|
|
</style>
|
|
|
```
|
|
|
|
|
|
### Props 定义
|
|
|
```javascript
|
|
|
props: {
|
|
|
// 基础类型
|
|
|
title: {
|
|
|
type: String,
|
|
|
required: true,
|
|
|
default: ''
|
|
|
},
|
|
|
// 对象类型
|
|
|
user: {
|
|
|
type: Object,
|
|
|
required: true,
|
|
|
default: () => ({})
|
|
|
},
|
|
|
// 数组类型
|
|
|
items: {
|
|
|
type: Array,
|
|
|
default: () => []
|
|
|
}
|
|
|
}
|
|
|
```
|
|
|
|
|
|
### 事件命名
|
|
|
```javascript
|
|
|
// 使用 kebab-case
|
|
|
this.$emit('user-updated', userData);
|
|
|
this.$emit('form-submitted', formData);
|
|
|
|
|
|
// 在模板中使用
|
|
|
<MyComponent @user-updated="handleUserUpdate" />
|
|
|
```
|
|
|
|
|
|
## 🎨 CSS/SCSS 规范
|
|
|
|
|
|
### 类名命名
|
|
|
```scss
|
|
|
// 使用 BEM 命名规范
|
|
|
.user-profile {
|
|
|
&__header {
|
|
|
// 元素
|
|
|
}
|
|
|
|
|
|
&--active {
|
|
|
// 修饰符
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// 或者使用 kebab-case
|
|
|
.user-profile {
|
|
|
.profile-header {
|
|
|
// 嵌套元素
|
|
|
}
|
|
|
|
|
|
&.is-active {
|
|
|
// 状态类
|
|
|
}
|
|
|
}
|
|
|
```
|
|
|
|
|
|
### 样式组织
|
|
|
```scss
|
|
|
// 1. 布局相关
|
|
|
.layout-container {
|
|
|
// 布局样式
|
|
|
}
|
|
|
|
|
|
// 2. 组件样式
|
|
|
.component-name {
|
|
|
// 组件样式
|
|
|
}
|
|
|
|
|
|
// 3. 工具类
|
|
|
.text-center {
|
|
|
text-align: center;
|
|
|
}
|
|
|
```
|
|
|
|
|
|
## 📊 JavaScript 规范
|
|
|
|
|
|
### 变量声明
|
|
|
```javascript
|
|
|
// 优先使用 const,需要重新赋值时使用 let
|
|
|
const API_URL = 'https://api.example.com';
|
|
|
const userConfig = { theme: 'dark' };
|
|
|
|
|
|
let currentUser = null;
|
|
|
let isLoading = false;
|
|
|
|
|
|
// 避免使用 var
|
|
|
// var userName = 'John'; // ❌
|
|
|
```
|
|
|
|
|
|
### 函数定义
|
|
|
```javascript
|
|
|
// 使用箭头函数
|
|
|
const fetchUser = async (userId) => {
|
|
|
try {
|
|
|
const response = await api.getUser(userId);
|
|
|
return response.data;
|
|
|
} catch (error) {
|
|
|
console.error('Failed to fetch user:', error);
|
|
|
throw error;
|
|
|
}
|
|
|
};
|
|
|
|
|
|
// 对象方法简写
|
|
|
const userService = {
|
|
|
async getUser(id) {
|
|
|
// 方法实现
|
|
|
},
|
|
|
|
|
|
async updateUser(id, data) {
|
|
|
// 方法实现
|
|
|
}
|
|
|
};
|
|
|
```
|
|
|
|
|
|
### 异步处理
|
|
|
```javascript
|
|
|
// 使用 async/await
|
|
|
async function handleSubmit() {
|
|
|
try {
|
|
|
this.loading = true;
|
|
|
const result = await this.submitForm();
|
|
|
this.$message.success('提交成功');
|
|
|
this.$router.push('/success');
|
|
|
} catch (error) {
|
|
|
this.$message.error('提交失败:' + error.message);
|
|
|
} finally {
|
|
|
this.loading = false;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// 避免使用 .then() 链式调用
|
|
|
// ❌ 不推荐
|
|
|
this.submitForm()
|
|
|
.then(result => {
|
|
|
// 处理结果
|
|
|
})
|
|
|
.catch(error => {
|
|
|
// 处理错误
|
|
|
});
|
|
|
```
|
|
|
|
|
|
## 🔧 API 调用规范
|
|
|
|
|
|
### 接口定义
|
|
|
```javascript
|
|
|
// api/user.js
|
|
|
import request from '@/utils/request'
|
|
|
|
|
|
export function getUserList(params) {
|
|
|
return request({
|
|
|
url: '/api/users',
|
|
|
method: 'get',
|
|
|
params
|
|
|
})
|
|
|
}
|
|
|
|
|
|
export function createUser(data) {
|
|
|
return request({
|
|
|
url: '/api/users',
|
|
|
method: 'post',
|
|
|
data
|
|
|
})
|
|
|
}
|
|
|
```
|
|
|
|
|
|
### 错误处理
|
|
|
```javascript
|
|
|
// 统一的错误处理
|
|
|
try {
|
|
|
const result = await api.getUserList(params);
|
|
|
this.userList = result.data;
|
|
|
} catch (error) {
|
|
|
// 根据错误类型处理
|
|
|
if (error.response?.status === 401) {
|
|
|
this.$router.push('/login');
|
|
|
} else {
|
|
|
this.$message.error(error.message || '操作失败');
|
|
|
}
|
|
|
}
|
|
|
```
|
|
|
|
|
|
## 📁 文件组织规范
|
|
|
|
|
|
### 目录结构
|
|
|
```
|
|
|
src/
|
|
|
├── api/ # API 接口
|
|
|
│ ├── user.js # 用户相关接口
|
|
|
│ └── course.js # 课程相关接口
|
|
|
├── components/ # 公共组件
|
|
|
│ ├── common/ # 通用组件
|
|
|
│ └── business/ # 业务组件
|
|
|
├── utils/ # 工具函数
|
|
|
│ ├── request.js # 请求封装
|
|
|
│ └── validate.js # 验证工具
|
|
|
└── views/ # 页面组件
|
|
|
├── user/ # 用户相关页面
|
|
|
└── course/ # 课程相关页面
|
|
|
```
|
|
|
|
|
|
### 导入顺序
|
|
|
```javascript
|
|
|
// 1. 第三方库
|
|
|
import Vue from 'vue'
|
|
|
import ElementUI from 'element-ui'
|
|
|
|
|
|
// 2. 项目内部模块
|
|
|
import { mapState } from 'vuex'
|
|
|
import UserService from '@/api/user'
|
|
|
|
|
|
// 3. 相对路径导入
|
|
|
import UserProfile from './UserProfile.vue'
|
|
|
import './styles/user.scss'
|
|
|
```
|
|
|
|
|
|
## 🧪 测试规范
|
|
|
|
|
|
### 测试文件命名
|
|
|
```
|
|
|
tests/
|
|
|
├── unit/ # 单元测试
|
|
|
│ ├── components/ # 组件测试
|
|
|
│ └── utils/ # 工具函数测试
|
|
|
└── e2e/ # 端到端测试
|
|
|
└── specs/ # 测试规范
|
|
|
```
|
|
|
|
|
|
### 测试用例命名
|
|
|
```javascript
|
|
|
describe('UserService', () => {
|
|
|
describe('getUser', () => {
|
|
|
it('should return user data when valid id provided', async () => {
|
|
|
// 测试实现
|
|
|
});
|
|
|
|
|
|
it('should throw error when invalid id provided', async () => {
|
|
|
// 测试实现
|
|
|
});
|
|
|
});
|
|
|
});
|
|
|
```
|
|
|
|
|
|
## 🔍 代码质量
|
|
|
|
|
|
### ESLint 规则
|
|
|
项目使用 ESLint 进行代码质量检查,主要规则包括:
|
|
|
- 强制使用分号
|
|
|
- 强制使用单引号
|
|
|
- 强制使用 2 空格缩进
|
|
|
- 禁止未使用的变量
|
|
|
- 强制使用 === 比较
|
|
|
|
|
|
### Prettier 配置
|
|
|
项目使用 Prettier 进行代码格式化,确保代码风格一致。
|
|
|
|
|
|
## 📝 注释规范
|
|
|
|
|
|
### 函数注释
|
|
|
```javascript
|
|
|
/**
|
|
|
* 获取用户信息
|
|
|
* @param {string} userId - 用户ID
|
|
|
* @param {Object} options - 请求选项
|
|
|
* @returns {Promise<Object>} 用户信息对象
|
|
|
*/
|
|
|
async function getUserInfo(userId, options = {}) {
|
|
|
// 函数实现
|
|
|
}
|
|
|
```
|
|
|
|
|
|
### 组件注释
|
|
|
```vue
|
|
|
<!--
|
|
|
用户信息组件
|
|
|
用于显示用户的基本信息和操作按钮
|
|
|
|
|
|
@props {Object} user - 用户信息对象
|
|
|
@props {Boolean} editable - 是否可编辑
|
|
|
@emits {string} user-updated - 用户信息更新事件
|
|
|
-->
|
|
|
<template>
|
|
|
<!-- 组件内容 -->
|
|
|
</template>
|
|
|
```
|
|
|
|
|
|
## 🚀 性能优化
|
|
|
|
|
|
### 组件优化
|
|
|
```javascript
|
|
|
// 使用 v-show 替代频繁的 v-if
|
|
|
<div v-show="isVisible">内容</div>
|
|
|
|
|
|
// 使用 key 优化列表渲染
|
|
|
<li v-for="item in list" :key="item.id">
|
|
|
{{ item.name }}
|
|
|
</li>
|
|
|
|
|
|
// 使用计算属性缓存结果
|
|
|
computed: {
|
|
|
filteredList() {
|
|
|
return this.list.filter(item => item.active);
|
|
|
}
|
|
|
}
|
|
|
```
|
|
|
|
|
|
### 懒加载
|
|
|
```javascript
|
|
|
// 路由懒加载
|
|
|
const UserList = () => import('@/views/user/UserList.vue');
|
|
|
|
|
|
// 组件懒加载
|
|
|
components: {
|
|
|
UserDetail: () => import('./UserDetail.vue')
|
|
|
}
|
|
|
```
|
|
|
|
|
|
## 📝 变更记录
|
|
|
|
|
|
| 版本 | 日期 | 变更内容 | 变更人 |
|
|
|
|------|------|----------|--------|
|
|
|
| v1.0.0 | 2024年 | 初始版本 | 开发团队 |
|
|
|
|
|
|
---
|
|
|
|
|
|
*如有疑问,请联系开发团队*
|