# 前端手册 ## 介绍 前端是基于[vue](https://github.com/vuejs/vue) 、[element-ui](https://panjiachen.github.io/vue-element-admin-site/zh/guide/)和[vue-element-admin](https://panjiachen.github.io/vue-element-admin-site/zh/)模板实现。它使用了最新的前端技术栈,内置了动态路由,权限验证,提炼了典型的业务模型,提供了丰富的功能组件。 ## 布局 页面整体布局是一个产品最外层的框架结构,往往会包含导航、侧边栏、面包屑以及内容等。想要了解一个后台项目,先要了解它的基础布局。 ## 路由和侧边栏 路由和侧边栏是组织起一个Web应用的关键骨架。 本项目侧边栏和路由是绑定在一起的,所以你只有在 @/router/index.js 下面配置对应的路由,侧边栏就能动态的生成了。大大减轻了手动重复编辑侧边栏的工作量。当然这样就需要在配置路由的时候遵循一些约定的规则。 路由除了分默认模板中的constantRoutes和asyncRoutes,还根据选择的应用分为了appRoutes和otherRoutes。 constantRoutes中存放了一些公用页面:应用管理、登录、404。 asyncRoutes中存放了登录后首页根据权限展示的页面:账号管理、集成文档、基础设置。 appRoutes中存放了点击应用后需要展示的侧边栏页面:版本管理、公告管理、成员管理。 otherRoutes中存放了无需在侧边栏中展示的菜单。 ### 配置 在@/router/index.js中,可以使用如下配置 ```javascript // 当设置 true 的时候该路由不会在侧边栏出现 如401,login等页面,或者如一些编辑页面/edit/1 hidden: true // (默认 false) //当设置 noRedirect 的时候该路由在面包屑导航中不可被点击 redirect: 'noRedirect' // 当你一个路由下面的 children 声明的路由大于1个时,自动会变成嵌套的模式--如组件页面 // 只有一个时,会将那个子路由当做根路由显示在侧边栏--如引导页面 // 若你想不管路由下面的 children 声明的个数都显示你的根路由 // 你可以设置 alwaysShow: true,这样它就会忽略之前定义的规则,一直显示根路由 alwaysShow: true name: 'router-name' // 设定路由的名字,一定要填写不然使用时会出现各种问题 meta: { roles: ['admin', 'editor'] // 设置该路由进入的权限,支持多个权限叠加 title: 'title' // 设置该路由在侧边栏和面包屑中展示的名字 icon: 'svg-name' // 设置该路由的图标,支持 svg-class,也支持 el-icon-x element-ui 的 icon noCache: true // 如果设置为true,则不会被 缓存(默认 false) breadcrumb: false // 如果设置为false,则不会在breadcrumb面包屑中显示(默认 true) affix: true // 如果设置为true,它则会固定在tags-view中(默认 false) // 当路由设置了该属性,则会高亮相对应的侧边栏。 // 这在某些场景非常有用,比如:一个文章的列表页路由为:/article/list // 点击文章进入文章详情页,这时候路由为/article/1,但你想在侧边栏高亮文章列表的路由,就可以进行如下设置 activeMenu: '/article/list' } ``` ### 示例 ```javascript { 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 // 不会被 缓存 } }] } ``` ## 请求流程 ### 交互流程 请求交互流程: 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字段控制。 ```javascript { 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来控制 ```javascript 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文件中配置。 例: ```javascript '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 就只会作用在当前组件内了,避免造成全局的样式污染。