前言
相信大家在从零开发后台管理系统的时候会遇到诸多问题,技术选型、UI组件、富文本选择等等。然而万事开头难,如何搭建最开始的后台框架或模板,我觉得是最为重要的一点。本文将采用花裤衩式的同款手模手,用简单的10个步骤,带你快速构建一个自己喜欢的可快速开发的后台模板。
先奉上成果: vue-antdesign-admin-template
技术选型
JavaScript 框架
建议选有对应 UI组件库 的前端框架去开发,可以在页面布局上节约很多时间。个人建议选目前市面上比较流行的三大框架VAR(Vue/Angular/React),对于这三哥俩,各有利弊,这里不做对比评论,可根据自己熟悉的框架或者团队更青睐的框架去选取。本文以Vue为例。
UI 组件库
Element | View UI(iView) | Ant Design of Vue 都是比较好的基于vue的高质量 UI 组件库。
可以根据自己或者团队喜好去选择,本次楼主尝试选择了Ant Design Of Vue。
鲁老先生曾经说过: “如果说我看得比别人更远些,那是因为我站在巨人的肩膀上。”
好吧,细心的观众老爷已经发现这不是鲁迅说的,没错,原话出自于牛顿。牛顿的多种研究确实是以哥白尼、伽利略、开普勒等诸多科学家的科研成果为基础的。

因此,学会站在巨人的肩膀上,是一种不错和可贵的策略。最近刷屏的《后浪》中也提到了这一点:“人类积攒了几千年的财富,所有的知识,见识,智慧和艺术,像是专门为你们准备的礼物,科技繁荣,文化繁茂,城市繁华,现代文明的成果被层层打开,可以尽情的享用...”sorry,有点跑题了,收回来。
在利用 Ant Design of Vue 搭建基础模板之前,有幸了解到这个项目:ANTD PRO VUE,此项目是 Ant Design Pro 的 Vue 版本,也是 Ant Design of Vue 的官方仓库,将它作为“巨人”,便开始了这次的搭(gai)建(zao)之路。
开始搭建
1.项目布局
对于大多数的后台项目,结构都是有共性且可复用的,因此将其抽离,作为相应的 Layout 很有必要,在前期我们将这个功能做好,后期会节约很多开发成本。
Ant Design Pro 抽离了使用过程中的通用布局,放在 /layouts 目录中,分别为:
- BasicLayout 基础页面布局,包含了全局头部导航,侧边栏和通知栏,设置抽屉等,是项目中的
Root Layout。 - UserLayout 抽离出用于登陆注册页面的通用布局。
- PageLayout 基础布局,包含了面包屑,和中间内容区 (slot)。
- RouteLayout 空布局,专门为了二级菜单内容区自定义。
- BlankLayout 空白的布局。
如何使用:
可以将 Layout 作为父级路由去嵌套子路由,例如:
// BasicLayout例子
{
path: '/',
name: 'index',
component: BasicLayout,
meta: { title: '首页' },
redirect: `${defaultRootRoutePath}/analysis`,
children: [
// 默认页
{
path: defaultRootRoutePath,
name: 'dashboard',
redirect: `${defaultRootRoutePath}/analysis`,
component: RouteLayout,
meta: { title: '工作台', keepAlive: true, icon: 'dashboard', permission: ['dashboard'] },
children: [
{
path: `${defaultRootRoutePath}/analysis`,
name: 'analysis',
component: () => import('@/views/dashboard/Analysis'),
meta: { title: 'hello', keepAlive: true, permission: ['dashboard'] },
},
],
},
exampleModle,
linkModle,
reportManageModle
],
}
// PageLayout例子
import { PageLayout } from '@/layouts'
const reportManageModle = {
path: '/reportManage',
name: 'reportManage',
redirect: '/reportManage/list',
component: PageLayout,
meta: { title: '举报管理', keepAlive: true, icon: 'frown', permission: ['dashboard'] },
children: [
{
path: '/reportManage/list',
name: 'reportManageList',
component: () => import('@/views/reportManage/list'),
meta: { title: '举报列表', keepAlive: true, permission: ['dashboard'] },
},
],
}
export default reportManageModle
2.环境区分
2.1 模式
模式是 Vue CLI 项目中一个重要的概念。默认情况下,一个 Vue CLI 项目有三个模式:
development模式用于vue-cli-service serveproduction模式用于vue-cli-service build和vue-cli-service test:e2etest模式用于vue-cli-service test:unit
需要注意的是:注意模式不同于 NODE_ENV,一个模式可以包含多个环境变量。也就是说,每个模式都会将 NODE_ENV 的值设置为模式的名称——比如在 development 模式下 NODE_ENV 的值会被设置为 "development"。
你可以通过为 .env 文件增加后缀来设置某个模式下特有的环境变量。比如,如果你在项目根目录创建一个名为 .env.development 的文件,那么在这个文件里声明过的变量就只会在 development 模式下被载入。
你可以通过传递 --mode 选项参数为命令行覆写默认的模式。例如,如果你想要在构建命令中使用开发环境变量,请在你的 package.json 脚本中加入相关配置,例如:
"build-prod": "vue-cli-service build --mode production_env",
"build-test": "vue-cli-service build --mode test_env",
2.2 环境变量
只有以 VUE_APP_ 开头的变量会被 webpack.DefinePlugin 静态嵌入到客户端侧的包中。你可以在应用的代码中这样访问它们:
console.log(process.env.VUE_APP_BASE_IMGURL)
特别提醒
除了 VUE_APP_* 变量之外,在你的应用代码中始终可用的还有两个特殊的变量:
NODE_ENV 会是 "development"、"production" 或 "test" 中的一个。具体的值取决于应用运行的模式。
BASE_URL 会和 vue.config.js 中的 publicPath 选项相符,即你的应用会部署到的基础路径。
我们可以根据自己的需要去配置环境变量,在不同模式中去配置不同的环境变量,当你根据命令去打包的时候环境变量会被自动替换,例如:
# .env.production_env
# API 地址
VUE_APP_API_BASE_URL = /api
# 打包输出地址
VUE_APP_OUTPUTDIR = 'dist_prod'
# antDesign 是否能够更换主题
VUE_APP_CAN_CHANGE_THEME = true
# 上传图片地址
VUE_APP_BASE_API_UPLOAD = 'https://httpbin.org/post'
# 获取图片地址
VUE_APP_BASE_IMGURL = 'https://httpbin.org/get'
3.代码规范
不管是多人运动还是单人运动,啊呸,口误...😂 —— 不管是多人开发还是单人开发,我觉得代码规范和代码格式都很重要,加分号还是不加分号?tab还是空格?单引号还是双引号?等等一系列的代码规范和校验问题,交给这两个家伙就好了:
关于它们,掘金社区有很多优秀的文章,大家可以自行搜索阅读,这里放一篇我看过觉得不错的: 使用ESLint+Prettier来统一前端代码风格
要配置它们,可在根目录下找到:
.prettierrc.js
.eslintrc.js
下面是 prettier 最常用到的配置,通常情况修改这几个配置项即可,也可以参考文档添加其他配置。
// .prettierrc.js
module.exports = {
printWidth: 150, // 一行的字符数,如果超过会进行换行,默认为80
tabWidth: 2, // 一个tab代表几个空格数,默认为2
singleQuote: true, // 字符串是否使用单引号,默认为false,使用双引号
semi: false, // 行尾部是否使用分号,默认为true
endOfLine: 'auto', // fix Delete `␍`eslint(prettier/prettier)
}
4.项目配置管理
后台项目一定会有很多配置项,将项目中用到的的配置抽离到 src/config 中统一管理,方便后期维护,例如:
├─icons.js ----- // 解决 @ant-design_icons 打包体积过大问题 采用按需加载
├─index.js ----- // 项目通用全局配置
└─layout.js ---- // 项目UI结构默认配置项
5.数据交互
5.1 request封装
数据交互是后台项目中必不可少且最重要的部分,通常我们会将请求方法封装起来统一使用。这里贴一下最简单的封装:(请求方法的封装可以根据后端和业务具体需求去特殊处理和扩展)
// request.js
import Vue from 'vue'
import axios from 'axios'
import store from '@/store'
import notification from 'ant-design-vue/es/notification'
import { VueAxios } from './axios'
import { TOKEN_NAME, prodUseMock } from '@/config/index'
let baseURL = prodUseMock ? '/api' : process.env.VUE_APP_API_BASE_URL
// 创建 axios 实例
const service = axios.create({
baseURL, // api base_url
timeout: 6000, // 请求超时时间
})
const err = (error) => {
if (error.response) {
const data = error.response.data
const token = Vue.ls.get(TOKEN_NAME)
if (error.response.status === 403) {
notification.error({
message: '被禁用的',
description: data.message,
})
}
if (error.response.status === 401 && !(data.result && data.result.isLoginRequest)) {
notification.error({
message: '非法访问',
description: '授权验证失败',
})
if (token) {
store.dispatch('Logout').then(() => {
setTimeout(() => {
window.location.reload()
}, 1500)
})
}
}
}
return Promise.reject(error)
}
// request interceptor
service.interceptors.request.use((config) => {
const token = Vue.ls.get(TOKEN_NAME)
if (token) {
config.headers['Access-Token'] = token // 让每个请求携带自定义 token 请根据实际情况自行修改
}
return config
}, err)
// response interceptor
service.interceptors.response.use((response) => {
return response.data
}, err)
const installer = {
vm: {},
install(Vue) {
Vue.use(VueAxios, service)
},
}
export { installer as VueAxios, service as axios }
建议将项目的请求按照模块进行归纳,统一放在 src/api 中管理。例如:github.com/yalin28/vue…
5.2 mock
在后端接口还没出来,在构建业务需要部分数据的时候可以考虑采取 Mock 来模拟数据请求,方便前期布局和处理业务等。
如何使用:
在 src/mock 目录中封装了简单的构造方法,可以参考 官方文档 去配置自己需要用到的 mock 数据。
如果你想更简单点,你可以采用大搜车团队开源的 Easy Mock 去模拟数据,使用方法可以参考我之前的文章:利用Easy Mock简单模拟开发数据接口
注意,mockjs 不支持 IE ,如果你需要考虑兼容 IE ,请不要再正式环境中使用它。
6.样式管理与主题定制
6.1样式管理
后台项目中,我们应该把多处用到的样式抽离出来统一管理,样式集合写在 src/style/ 目录下,我们可以结合css预处理器将常用的样式片段做成 mixins。
例如:
我们可以将 vue 路由切换的动画效果写在 src/style/transition.less 中,此目录 中提供了两种切换效果,可以根据需要去切换和关闭。
我们可以将 less函数和变量 写在 src/style/utils.less 中。
在这次 vue-antdesign-admin-template 的构建中,由于UI组件库使用的 less,为了兼容性,项目选择 less 作为预处理器,为了能使用全局的 less函数,我们需要引入 style-resources-loader 工具,可以将自定义的全局 less 函数用到任意 view 或 components 中。(如果你使用的是其他预处理器可以自行处理,配置大同小异。)
使用 style-resources-loader 需要安装 style-resources-loader 和 vue-cli-plugin-style-resources-loader
然后在 vue.config.js 的 pluginOptions 中配置:
// src/style/utils.less 对应你需要注入的全局样式和less函数
pluginOptions: {
'style-resources-loader': {
preProcessor: 'less',
// 注入全局样式
patterns: [path.resolve(__dirname, 'src/style/utils.less')],
},
},
例如以下常用的三个 less 函数:
// 字体颜色
.sc(@size, @color) {
font-size: @size;
color: @color;
}
// 文本水平居中
.tc() {
text-align: center;
}
// 文本垂直居中
.hl(@param) {
height: @param;
line-height: @param;
}
使用案例,设置 p标签 文字大小为 14像素 、文字颜色为 橙色 且单行文本 水平垂直居中 :
<style scoped lang="less">
p{
.tc()
.sc(14px,orange)
.hl(1em)
}
</style>
6.2 主题定制
Antdesign 的样式使用了 Less 作为开发语言,并定义了一系列全局/组件的样式变量,你可以根据需求进行相应调整。
一些常用的变量:
@primary-color: #1890ff; // 全局主色
@link-color: #1890ff; // 链接色
@success-color: #52c41a; // 成功色
@warning-color: #faad14; // 警告色
@error-color: #f5222d; // 错误色
@font-size-base: 14px; // 主字号
@heading-color: rgba(0, 0, 0, 0.85); // 标题色
@text-color: rgba(0, 0, 0, 0.65); // 主文本色
@text-color-secondary: rgba(0, 0, 0, 0.45); // 次文本色
@disabled-color: rgba(0, 0, 0, 0.25); // 失效色
@border-radius-base: 4px; // 组件/浮层圆角
@border-color-base: #d9d9d9; // 边框色
@box-shadow-base: 0 2px 8px rgba(0, 0, 0, 0.15); // 浮层阴影
需要了解所有可以配置的变量:请点我
如何定制:
antDesign Of Vue 使用 modifyVars 的方式来进行覆盖变量。
以 webpack@4 为例进行说明,对 less-loader 的 options 属性进行相应配置。如果使用的是 Vue CLI 构建项目,修改 vue.config.js 中 css loaderOptions 的配置即可:
loaderOptions: {
less: {
modifyVars: {
// 通过修改默认ant主题的less变量实现自定义主题
// 'primary-color': 'red',
// 'link-color': 'red',
// 'border-radius-base': '0px',
},
javascriptEnabled: true,
},
},
或者你没使用 Vue CLI:
// webpack.config.js
module.exports = {
rules: [{
test: /\.less$/,
use: [{
loader: 'style-loader',
}, {
loader: 'css-loader', // translates CSS into CommonJS
}, {
loader: 'less-loader', // compiles Less to CSS
+ options: {
+ modifyVars: {
+ 'primary-color': '#1DA57A',
+ 'link-color': '#1DA57A',
+ 'border-radius-base': '2px',
+ },
+ javascriptEnabled: true,
+ },
}],
// ...other rules
}],
// ...other config
}
6.3 整体风格设置
可不可以快速地、可视化地去配置项目的整体风格呢?答案是肯定的,ANTD PRO VUE 提供了一个可快速设置项目整体UI风格的 SettingDrawer,可以快速设置主题色,导航模式,多标签模式等。设置后会以本地缓存的模式记录配置,下次加载页面的时候会判断是否有缓存并持续生效。
作为一个后台模板,这个功能虽然不是必要的,但却有画龙点睛之用。你说我是愿意去手搓代码写配置呢还是拿起鼠标点点点呢?🤪

7.权限控制
权限控制是后台系统中最常见的功能,通常是根据后端接口获取用户角色,根据角色获取对应的权限(路由)。
在 vue 项目中,我们可以根据路由去控制权限,根据当前登录的用户对应的角色权限去生成路由表,通过 router.addRoutes 动态挂载到 router。
具体实现可参考 src/permission.js 和 src/store/modules/permission.js
如果不需要权限控制,移除main.js 对应的引入,修改 src/config/index.js 中的 openPermission 即可。
8.状态管理
后台项目南面涉及到多页面数据共享和数据持久化的问题。要处理这些问题,我们可以采取 Vuex + vue-ls 的策略。
Vuex 这里不多说,如果你项目很小的话,你也可以考虑不用它,毕竟用了会增加很多额外的工作。
vue-ls 可以让你的数据持久化,比如主题设置。其原理是将数据写入 localstorage 。在 src/config/index.js 中的 storageOptions 可以对 vue-ls 去进行配置。
9.富文本编辑器
后台项目当然少不了富文本编辑器,选一个你钟意的富文本编辑器,把它做成组件装入你的后台模板中。楼主早期有用过百度的 UE ,但是 UE 的坑很多,UI界面和 AntDesign 显得格格不入,后面在大佬的安利下,入手了
Tinymce 。
组件源码来源于 panjiachen 大佬,稍微作了修改,兼容了 AntDesign。组件位于 src/components/Tinymce,可以根据业务去具体调整和修改。本次搭建模板的富文本例子可以 点此预览
如果你需要用其他富文本,思路也是一样的,单独抽离出来封装成一个组件。 不知道该怎么去选择富文本编辑器的可以参考大佬的文档:vue-element-admin | 富文本
10.项目优化
感谢亲爱的读者你都能读到第10步,离成功就差一点了👏👏👏 。
最后一步:项目优化。
如何去对搭建好的的项目优化,或许我们可以这样去做(或许都是我们耳熟能详的处理方法,但是这些真的很有用!)
- 合理的项目目录,让项目结构清晰,后期方便维护和迭代。
- 开启gzip压缩,减少请求内容体积。
- assetsCDN,加快页面响应。
- 按需加载组件,例如 src/config/icons.js 和 src/core/lazy_lib/components_use.js 的按需加载配置,可以根据所选择的
UI组件库去配置。 - 避免将不需要的组件打包。
- 通过运行命令
vue-cli-service build --report查看打包分析,对应调整。Vue Cli给我们提供了打包分析,配置在package.json中可以快速打包分析,如果没用VueCli构建项目也可以手动安装打包分析的插件。
最后
本文以 vue-antdesign-admin-template 为例子,介绍了用 antDesign+Vue 搭建一个快速开发的后台模板一个定制和构建的模板需要去做哪些工作,和具体的步骤。搭建好模板后,后期项目需要的就是往里面添砖加瓦,盖起项目“楼层”即可,对于开发后台项目会有事半功倍的效果。
再次感谢为我们提供轮子的大佬们,让我们可以成为配置工程师,同时我也希望有朝一日也能成为像大佬们那样优秀的人,加油!
如果你喜欢本文章或者文章对你有帮助或是启发的话,欢迎评论交流,也可以一键三连(什么,你连三连是啥都不知道?😲,让我告诉你:点赞 + 评论 + star)。如果文章有错误或者遗漏之处,望帮忙指出,感谢!