# 前端手册
# 介绍
前端是基于vue (opens new window) 、element-ui (opens new window)和vue-element-admin (opens new window)模板实现。它使用了最新的前端技术栈,内置了动态路由,权限验证,提炼了典型的业务模型,提供了丰富的功能组件。
# 布局
页面整体布局是一个产品最外层的框架结构,往往会包含导航、侧边栏、面包屑以及内容等。想要了解一个后台项目,先要了解它的基础布局。
# 路由和侧边栏
路由和侧边栏是组织起一个Web应用的关键骨架。
本项目侧边栏和路由是绑定在一起的,所以你只有在 @/router/index.js 下面配置对应的路由,侧边栏就能动态的生成了。大大减轻了手动重复编辑侧边栏的工作量。当然这样就需要在配置路由的时候遵循一些约定的规则。
路由除了分默认模板中的constantRoutes和asyncRoutes,还根据选择的应用分为了appRoutes和otherRoutes。
constantRoutes中存放了一些公用页面:应用管理、登录、404。
asyncRoutes中存放了登录后首页根据权限展示的页面:账号管理、集成文档、基础设置。
appRoutes中存放了点击应用后需要展示的侧边栏页面:版本管理、公告管理、成员管理。
otherRoutes中存放了无需在侧边栏中展示的菜单。
# 配置
在@/router/index.js中,可以使用如下配置
// 当设置 true 的时候该路由不会在侧边栏出现 如401,login等页面,或者如一些编辑页面/edit/1
hidden: true // (默认 false)
//当设置 noRedirect 的时候该路由在面包屑导航中不可被点击
redirect: 'noRedirect'
// 当你一个路由下面的 children 声明的路由大于1个时,自动会变成嵌套的模式--如组件页面
// 只有一个时,会将那个子路由当做根路由显示在侧边栏--如引导页面
// 若你想不管路由下面的 children 声明的个数都显示你的根路由
// 你可以设置 alwaysShow: true,这样它就会忽略之前定义的规则,一直显示根路由
alwaysShow: true
name: 'router-name' // 设定路由的名字,一定要填写不然使用<keep-alive>时会出现各种问题
meta: {
roles: ['admin', 'editor'] // 设置该路由进入的权限,支持多个权限叠加
title: 'title' // 设置该路由在侧边栏和面包屑中展示的名字
icon: 'svg-name' // 设置该路由的图标,支持 svg-class,也支持 el-icon-x element-ui 的 icon
noCache: true // 如果设置为true,则不会被 <keep-alive> 缓存(默认 false)
breadcrumb: false // 如果设置为false,则不会在breadcrumb面包屑中显示(默认 true)
affix: true // 如果设置为true,它则会固定在tags-view中(默认 false)
// 当路由设置了该属性,则会高亮相对应的侧边栏。
// 这在某些场景非常有用,比如:一个文章的列表页路由为:/article/list
// 点击文章进入文章详情页,这时候路由为/article/1,但你想在侧边栏高亮文章列表的路由,就可以进行如下设置
activeMenu: '/article/list'
}
# 示例
{
path: '/permission',
component: Layout,
redirect: '/permission/index', //重定向地址,在面包屑中点击会重定向去的地址
hidden: true, // 不在侧边栏显示
alwaysShow: true, //一直显示根路由
meta: { roles: ['admin','editor'] }, //你可以在根路由设置权限,这样它下面所有的子路由都继承了这个权限
children: [{
path: 'index',
component: ()=>import('permission/index'),
name: 'permission',
meta: {
title: 'permission',
icon: 'lock', //图标
roles: ['admin','editor'], //或者你可以给每一个子路由设置自己的权限
noCache: true // 不会被 <keep-alive> 缓存
}
}]
}
# 请求流程
# 交互流程
请求交互流程:
1.调用@/src/api中统一管理的 api service 请求函数;
2.使用封装的 axios.js 发送请求;
3.获取服务端返回,在这里处理后台对应的respondCode处理;
4.更新 data;
为了方便管理维护,统一的请求处理都放在 @/src/api 文件夹中,并且一般按照模块进行拆分文件,如:
api/
login.js
appEdit.js
noticeEdit.js
...
提示
其中,@/api/axios.js 是基于 axios 的封装,便于统一处理 POST,GET 等请求参数,请求头,以及错误提示信息等。 它封装了全局 request拦截器、response拦截器、统一的错误处理、统一做了超时处理、baseURL设置等。
# 权限介绍
权限管理分为两块:
首页的侧栏菜单通过登录后的isAdmin字段控制。
{
path: '/account',
name: 'account',
component: Wapper,
isAdmin: 1,
children:[
{
path:'account',
component: ()=> import("@/views/account/accountManagement"),
name: '账号管理',
meta: { title: '账号管理', icon: 'main-account', noCache: false, affix: true }
}
]
}
应用内的侧栏菜单通过appId和userId字段调用接口selectMenuPermissionsByAppIDAndUserId获取perm来控制
SetCurrentRoutes({ commit }, path) {
return new Promise(resolve => {
let currentRoutes
if (path.startsWith('/app/')) {
let appinfo = JSON.parse(sessionStorage.getItem('APPINFO'))
var perms = appinfo.perms
console.log('当前perms:', perms);
const routes = perms.map(function(p){
return appRoutes.find(function(r){
return r.perms == p;
});
})
console.log('当前路由:', routes);
//动态加权限
currentRoutes= routes;
}else {
var accessUser = store.getters.accessUser
if(accessUser == null) {
accessUser = JSON.parse(sessionStorage.getItem('ACCESSUSER'))
}
if (accessUser != null && accessUser.isAdmin == 1){ //admin
//动态加权限
currentRoutes = constantRoutes.concat(asyncRoutes)
} else {
//排除用户管理
currentRoutes = constantRoutes.concat(asyncRoutes.filter((item) => {
return item.isAdmin == 0;
}))
}
}
commit('SET_MENU_ROUTES', currentRoutes)
resolve(currentRoutes)
})
}
# 环境配置
根据开发、测试、uat、生产四个环境,分别在@/config目录下对应的dev.env.js、test.env.uat.env.js、prod.env.js文件中配置。 例:
'use strict'
const merge = require('webpack-merge')
const prodEnv = require('./prod.env')
module.exports = merge(prodEnv, {
NODE_ENV: '"development"',
BASE_API: '"http://xxx.xxxx.com/sp"', //开发环境
})
// npn run dev:test
# 扩展开发规范
除了现有的功能外,开发者可以根据自己的业务需要,自行拓展其他模块。
# 新增页面
在 @/views (opens new window) 文件下 创建对应的文件夹,一般性一个路由对应一个文件, 该模块下的功能就建议在本文件夹下创建一个新文件夹,各个功能模块维护自己的utils或components组件。
# 新增api
在 @/api (opens new window) 文件夹下创建本模块对应的 api 服务。
# 新增组件
在全局的 @/components (opens new window) 写一些全局的组件,如富文本,各种搜索组件,封装的分页组件等等能被公用的组件。 每个页面或者模块特定的业务组件则会写在当前 @/views (opens new window) 下面。
# 新增样式
页面的样式和组件是一个道理,全局的 @/style (opens new window) 放置一下全局公用的样式,每一个页面的样式就写在当前 views下面,请记住加上scoped 就只会作用在当前组件内了,避免造成全局的样式污染。