Appearance
前端管理后台开发指南
本指南概述了采用 Vue 3、Vite 与 Element Plus 构建的 PC 端管理后台(Admin端)的开发规范与核心功能模块机制。
📋 前序准备
环境要求
- Node.js:推荐版本 >= 18.0.0 (支持更新特性的前端构建)
- npm:Node.js 自带的包管理工具
- 编辑器:推荐使用 Visual Studio Code
手动校验代码
执行命令:
bash
npm run lint📁 目录结构
项目采用清晰的模块化结构,便于开发和维护:
text
├──📂 public # 公共资源文件
├──📂 scripts # 工程自动化运行或执行依赖的辅助脚本
├──📂 src # 核心源代码
│ ├──📂 api # 对应后端模块定义的请求接口封装
│ ├──📂 assets # 静态资源文件
│ ├──📂 components # 全局公用组件
│ ├──📂 directive # 自定义指令
│ ├──📂 layout # 框架版型布局
│ ├──📂 router # 路由
│ ├──📂 stores # 全局状态管理
│ ├──📂 styles # 全局样式
│ ├──📂 utils # 工具函数库
│ ├──📂 views # 所有页面
│ ├── App.vue # 入口页面
│ ├── main.ts # 入口文件 各个生态依赖的进入和注册点
│ ├── permission.ts # 前台路由拦截,权限管理
│ └── settings.ts # 系统配置
├── .env.development # 开发环境变量配置
├── .env.production # 生产环境变量配置
├── .eslintrc.cjs # ESLint 检测工具规则
├── .prettierrc.json # 团队化统一代码外观格式控制
├── index.html # 入口文件
├── package.json # Node 运行时必需引用的包含库
├── postcss.config.js # postcss 配置项
├── tailwind.config.js # tailwindcss 配置项
├── tsconfig.json # ts 配置项
└── vite.config.ts # vite 配置项🧭 一、路由设计 (Router)
为了兼顾系统安全与灵活的权限控制,路由(Router)被设计为两级部分协同工作:静态路由与动态路由。
1.静态路由
主要包含那些不需要受到严格权限系统监管的基础页面(例如:登录页、404错误页,以及所有管理员在任意权限下都可以进入的个人设置等)。 相关配置统一在 src/router/routes.ts 文件内控制。
ts
// 路由配置项
{
path: '/path', // 路由路径
name: 'routerName', // 路由名称
meta: {
title: 'title', // 路由在侧边栏与多签页的显示名称
icon: 'iconName', // 路由图标
iconType: 1, // 图标类型:1-ElementPlus图标,2-本地图标
keepAlive: true, // 是否缓存路由
query: { id: 1 }, // 访问路由的默认传递参数
activeMenu: '/system/example' // 高亮对应侧边栏的菜单
hidden: false, // 控制路由是否在侧边栏展示
},
component: () => import('@/views/example/index.vue') // 路由组件
}2.动态路由(基于菜单生成)
具体带有业务属性的模块(例如用户管理、系统管理)均属于动态路由。管理员不需要在代码里写死这部分页面的路由,而是通过在系统后台的菜单管理功能动态添加。
路径:权限管理 -> 菜单 -> 新增。
服务端下发的菜单数据会由前端状态机过滤转换后,动态通过 router.addRoute 的形式插入到当前路由表中。
🔒 二、菜单与权限 (Permission)
后台界面深度使用了 RBAC(基于角色的访问控制)模型。整个权限流转体现在界面的渲染拆分上:
1.页面级权限(动态菜单拦截)
登录成功后服务端返回该人员有访问权限的菜单树。前台通过递归对比权限编码,凡是不在返回列表中的页面组件,从源头上不会被注册至 Vue Router。进而达到无权限用户强行在地址栏输入访问也会被重定向至 403 的效果。
2.按钮级权限(指令级控制)
在实际业务场景中,可能存在不同角色都能访问同一页面,但操作权限不同的情况(例如:都能查看文章列表,但只有特定角色可以编辑或删除文章)。针对这种场景,项目提供了自定义指令 v-perms 来实现按钮级别的权限控制。
该指令会根据用户拥有的权限列表,判断是否渲染对应的元素。只有当用户拥有指令中指定的权限时,元素才会被显示和渲染。
html
<template>
<!-- 直接将对应的后端接口权限标识写入,如果命中匹配则渲染该按钮 -->
<el-button v-perms="['auth.admin/edit']">编辑</el-button>
<!-- 支持由多个指令组成的或操作 -->
<el-button v-perms="['auth.admin/edit', 'auth.admin/add']">编辑或新增</el-button>
</template>📡 三、接口请求层 (Axios 封装)
接口与网络的交互统一由根目录 src/utils/request 模块接管。我们在基础的 Axios 上封装了多种业务拦截器。
文件树解析:
text
src/utils/request
├── axios.ts // 纯正底层封装的 Axios 完整派生工厂函数
├── index.ts // 对外暴漏供组件直接引入的聚合模块,统一管理鉴权头、超时时间、错误处理等请求拦截生命周期:
- 请求前拦截:系统自动给 Header 塞进如
Authorization等身份认证专属 Token 数据,并在发起前计算接口加密签名字段(若启用)。 - 拿到数据判断:直接判断最外层的业务响应状态码(比如
code: 1视为通过),直接抛出data底层有效载体跳过开发者的手写判断。 - 全局错判容灾:遇到
code: 0则自动触发 Element 的错误 Toast,遇到被服务端强踢的401过期状态则拉取用户强制退回登录页。
⚙️ 四、配置项
环境变量配置
项目使用 Vite 的环境变量机制,变量命名规则需以 VITE_ 为前缀。
开发环境配置
文件路径:.env.development
env
# 开发环境
NODE_ENV=development
# API地址
VITE_API_BASE_URL=生产环境配置
文件路径:.env.production
env
# 生产环境
NODE_ENV=production
# API地址
VITE_API_BASE_URL=🗄️ 五、状态管理 (Pinia)
项目使用 Pinia 作为状态管理工具,替代了传统的 Vuex,提供了更简洁的 API 和更好的 TypeScript 支持。
状态管理模块
文件路径:src/stores/modules/
- config.ts - 系统配置状态管理
- setting.ts - 系统设置状态管理,将用户设置保存到浏览器缓存中
- tabs.ts - 标签页状态管理
- user.ts - 用户信息状态管理
使用示例
ts
import { useUserStore } from '@/stores/modules/user'
const userStore = useUserStore()
// 获取用户信息
userStore.getUserInfo()
// 登出
userStore.logout()🧩 六、常用组件
项目中封装了一些常用的公共组件,方便开发使用。
1.编辑器组件 (Editor)
基于 WangEditor 封装的富文本编辑器组件,支持图片上传、视频插入等功能。
使用示例:
html
<template>
<Editor v-model="content" />
</template>2.图标组件 (Icon)
封装了 Element Plus 的图标组件,提供统一的图标使用方式。
使用示例:
html
<template>
<Icon name="Edit" :type="1" />
</template>3.素材管理组件 (Material)
用于管理和选择素材文件,包含多个子组件:
- Catalog:素材分类管理
- File:文件管理
- List:素材列表
- Picker:素材选择器
- Preview:素材预览
使用示例:
html
<template>
<material-picker v-model="formData.image" :limit="1" />
</template>4.分页组件 (Pagination)
封装了 Element Plus 的分页组件,支持自定义样式和事件。
使用示例:
html
<template>
<Pagination v-model="queryParams" :total="total" @change="getLists" />
</template>5.弹窗组件 (Popup)
封装了 Element Plus 的对话框组件,支持自定义内容和样式。
使用示例:
html
<template>
<popup v-model="visible" width="600px" title="弹窗标题" @confirm="handleConfirm">
<div>弹窗内容</div>
</popup>
</template>6.上传组件 (Upload)
封装了 Element Plus 的上传组件,支持图片、视频等文件的上传。
使用示例:
html
<template>
<upload type="image" :show-progress="true" @allSuccess="handleUpload">
<el-button type="primary" icon="Upload">上传图片</el-button>
</upload>
</template>🛠️ 七、组件注册与前端配置
为了能让开发过程达到沉浸式的飞快体验,Vue 和周边工具做了大量免操作约定。
1.自动引入与组件注册
基于工程化配置了如下自动加载引擎:
unplugin-auto-import:在任意 Vue/Ts 页面写代码时,直接写ref(),reactive()或useRouter(), 构建时会自动引入依赖包,无需手动使用import { ref } from 'vue'。unplugin-vue-components:项目中放置于src/components下的所有公共组件及element-plus,将支持在 HTML 中直接插标渲染,全网无需手动宣告局部 Component 对象注册。
2.样式及 TailwindCSS 混合使用
本项目集成了预处理利器 SCSS 并搭载 TailwindCSS 原子化框架。
如果页面需要极其灵活的布局或内外边距颜色调试,推荐不再新建单文件 scoped SCSS,而是直接利用 Tailwind 类写就页面的绝大部分样式:
html
<div class="flex items-center justify-between p-4 bg-white rounded-lg shadow-sm hover:shadow">
<span class="text-gray-700 font-bold">后台模块</span>
</div>全局的样式补丁或是需要更改深层 Element-Plus 元组件的变量,都统一集合在 src/styles 根目录集中复写。
ℹ️ 温馨提示: 如果团队协作对统一风格有极高要求的规范,建议每次合并代码前通过根目录下的
.eslintrc.cjs及.prettierrc.json执行npm run lint验证自动规范容错。
