Skip to content

Admin 开发规范

目录


1. 功能说明

概述

本文档规定 Admin 端的开发规范,包括代码风格、组件使用、状态管理等方面。

适用场景

  • Admin 端功能开发
  • 代码审查参考
  • 团队协作规范

2. 设计思路

规范目标

  • 提高代码可读性
  • 统一代码风格
  • 降低维护成本
  • 提升开发效率

3. 代码规范

3.1 文件命名规范

类型命名方式示例
组件文件PascalCaseUserList.vue
工具文件camelCaserequest.ts
样式文件kebab-casecommon-style.scss
常量文件SNAKE_CASEAPI_CONFIG.ts

3.2 组件规范

组件结构

vue
<template>
  <!-- 模板内容 -->
</template>

<script setup lang="ts">
// 1. 导入
import { ref, computed } from 'vue';
import type { PropType } from 'vue';

// 2. 类型定义
interface UserInfo {
  id: number;
  name: string;
}

// 3. Props 定义
const props = defineProps({
  userId: {
    type: Number as PropType<number>,
    required: true
  }
});

// 4. Emits 定义
const emit = defineEmits<{
  (e: 'update', value: UserInfo): void;
}>();

// 5. 响应式数据
const loading = ref(false);
const userInfo = ref<UserInfo | null>(null);

// 6. 计算属性
const displayName = computed(() => {
  return userInfo.value?.name || '未知';
});

// 7. 方法
const fetchUserInfo = async () => {
  loading.value = true;
  try {
    // 请求数据
  } finally {
    loading.value = false;
  }
};

// 8. 生命周期
onMounted(() => {
  fetchUserInfo();
});
</script>

<style scoped lang="scss">
/* 样式内容 */
</style>

组件命名

vue
<!-- 单文件组件命名 -->
<!-- 推荐 -->
<UserList />
<user-list />

<!-- 不推荐 -->
<userlist />
<userList />

3.3 TypeScript 规范

类型定义

typescript
// 接口定义
interface User {
  id: number;
  name: string;
  email?: string;  // 可选属性
}

// 类型别名
type UserStatus = 'active' | 'inactive' | 'banned';

// 枚举定义
enum UserRole {
  Admin = 'admin',
  User = 'user',
  Guest = 'guest'
}

函数定义

typescript
// 函数声明
function getUserById(id: number): Promise<User> {
  return request.get(`/api/user/${id}`);
}

// 箭头函数
const handleSubmit = async (data: UserForm): Promise<void> => {
  await saveUser(data);
};

3.4 API 封装规范

typescript
// src/api/sys/user.ts
import request from '@/utils/request';
import type { User, UserQuery, UserForm } from './types';

/**
 * 获取用户列表
 * @param params 查询参数
 */
export function getUserList(params: UserQuery) {
  return request.get<PageResult<User>>('/adminapi/sys/user/list', { params });
}

/**
 * 获取用户详情
 * @param id 用户ID
 */
export function getUserDetail(id: number) {
  return request.get<User>(`/adminapi/sys/user/${id}`);
}

/**
 * 添加用户
 * @param data 用户数据
 */
export function addUser(data: UserForm) {
  return request.post('/adminapi/sys/user', data);
}

/**
 * 编辑用户
 * @param id 用户ID
 * @param data 用户数据
 */
export function editUser(id: number, data: UserForm) {
  return request.put(`/adminapi/sys/user/${id}`, data);
}

/**
 * 删除用户
 * @param id 用户ID
 */
export function deleteUser(id: number) {
  return request.delete(`/adminapi/sys/user/${id}`);
}

3.5 状态管理规范

typescript
// src/stores/modules/user.ts
import { defineStore } from 'pinia';
import { getUserInfo } from '@/api/sys/user';
import type { UserInfo } from '@/api/sys/types';

interface UserState {
  info: UserInfo | null;
  token: string;
  permissions: string[];
}

export const useUserStore = defineStore('user', {
  state: (): UserState => ({
    info: null,
    token: localStorage.getItem('token') || '',
    permissions: []
  }),

  getters: {
    isLogin: (state) => !!state.token,
    userName: (state) => state.info?.username || ''
  },

  actions: {
    // 设置 Token
    setToken(token: string) {
      this.token = token;
      localStorage.setItem('token', token);
    },

    // 获取用户信息
    async fetchUserInfo() {
      try {
        const res = await getUserInfo();
        this.info = res.data;
        this.permissions = res.data.permissions || [];
        return res.data;
      } catch (error) {
        return Promise.reject(error);
      }
    },

    // 退出登录
    logout() {
      this.token = '';
      this.info = null;
      this.permissions = [];
      localStorage.removeItem('token');
    }
  }
});

3.6 样式规范

SCSS 使用

scss
// 变量定义
$primary-color: #409eff;
$text-color: #303133;
$border-color: #dcdfe6;

// 混合宏
@mixin flex-center {
  display: flex;
  justify-content: center;
  align-items: center;
}

// 组件样式
.user-list {
  padding: 20px;
  
  &__header {
    margin-bottom: 16px;
    @include flex-center;
    justify-content: space-between;
  }
  
  &__table {
    border: 1px solid $border-color;
    
    :deep(.el-table__header) {
      background-color: #f5f7fa;
    }
  }
}

3.7 注释规范

typescript
/**
 * 用户管理组件
 * @description 用于管理系统用户列表
 * @author Niucloud Team
 * @since 2026-04-08
 */

/**
 * 获取用户列表
 * @param params 查询参数
 * @param params.page 页码
 * @param params.limit 每页数量
 * @returns 用户列表数据
 * @example
 * const list = await getUserList({ page: 1, limit: 10 });
 */
function getUserList(params: UserQuery): Promise<PageResult<User>> {
  // 实现代码
}

4. 常见问题

Q1: 如何组织大型组件

推荐做法:

UserDetail/
├── index.vue          # 主组件
├── UserInfo.vue       # 用户信息子组件
├── UserOrder.vue      # 用户订单子组件
├── UserLog.vue        # 用户日志子组件
├── composables/
│   └── useUser.ts     # 组合式函数
└── types.ts           # 类型定义

Q2: 如何处理表单验证

vue
<script setup lang="ts">
import type { FormInstance, FormRules } from 'element-plus';

const formRef = ref<FormInstance>();
const formData = reactive({
  username: '',
  email: ''
});

const rules: FormRules = {
  username: [
    { required: true, message: '请输入用户名', trigger: 'blur' },
    { min: 3, max: 20, message: '长度在 3 到 20 个字符', trigger: 'blur' }
  ],
  email: [
    { required: true, message: '请输入邮箱', trigger: 'blur' },
    { type: 'email', message: '邮箱格式不正确', trigger: 'blur' }
  ]
};

const submitForm = async () => {
  const valid = await formRef.value?.validate();
  if (valid) {
    // 提交表单
  }
};
</script>

修订记录

版本日期修订人修订内容
v1.02026-04-08Niucloud Team初始版本