基于vue-admin-template二次开发

1、添加路由 新增页面组件

  1. // 静态路由
  2. export const constantRoutes = [
  3. {
  4. path: '/login',
  5. component: () => import('@/views/login/index'),
  6. hidden: true
  7. },
  8. {
  9. path: '/',
  10. component: Layout,
  11. redirect: '/appointment/index'
  12. },
  13. {
  14. path: '/appointment',
  15. component: Layout,
  16. children: [
  17. {
  18. path: 'index',
  19. name: 'appointment',
  20. component: () => import('@/views/appointment/index'),
  21. meta: { title: '预约中心', icon: 'form' }
  22. }
  23. ]
  24. }
  25. ]
  26. // 动态路由
  27. export const asyncRouterMap = [
  28. {
  29. path: '/manage',
  30. component: Layout,
  31. name: 'manage',
  32. meta: { title: '管理中心', icon: 'el-icon-s-help', breadcrumb: false, role: ['admin', 'teacher'] },
  33. children: [
  34. {
  35. path: 'appointmentManage',
  36. name: 'appointmentManage',
  37. component: () => import('@/views/management/appointmentManage/index'),
  38. meta: { title: '预约管理', icon: 'el-icon-s-order', role: ['admin', 'teacher'] }
  39. },
  40. {
  41. path: 'userManage',
  42. name: 'userManage',
  43. component: () => import('@/views/management/userManagement/index'),
  44. meta: { title: '用户管理', icon: 'el-icon-user-solid', role: ['admin', 'teacher'] }
  45. },
  46. {
  47. path: 'roomManage',
  48. name: 'roomManage',
  49. component: () => import('@/views/management/roomManagement/index'),
  50. meta: { title: '实验室管理', icon: 'el-icon-s-home', role: ['admin', 'teacher'] }
  51. }
  52. ]
  53. },
  54. // 404 page must be placed at the end !!!
  55. {
  56. path: '/404',
  57. component: () => import('@/views/404'),
  58. hidden: true
  59. },
  60. { path: '*', redirect: '/404', hidden: true }]

2、规范创建组件和接口文件

基于vue-admin-template二次开发 - 图1基于vue-admin-template二次开发 - 图2

3、api中存后端接口,组件中调用api

  1. export function login(data) {
  2. return request({
  3. url: '/user/login',
  4. method: 'post',
  5. data
  6. })
  7. }

4、修改request.js

  1. // 从vuex中拿token
  2. if (store.getters.token) {
  3. // let each request carry token
  4. // ['X-Token'] is a custom headers key
  5. // please modify it according to the actual situation
  6. config.headers['tokenName'] = getToken()
  7. }
  8. // if the custom code is not 200, it is judged as an error. 根据后端返回的code修改
  9. if (res.code !== 200) {
  10. Message({
  11. message: res.msg || 'Error',
  12. type: 'error',
  13. duration: 5 * 1000
  14. })

5、根据自己的需要修改store

  1. const getters = {
  2. sidebar: state => state.app.sidebar,
  3. device: state => state.app.device,
  4. token: state => state.user.token,
  5. name: state => state.user.name,
  6. userId: state => state.user.userId,
  7. studentId: state => state.user.studentId,
  8. college: state => state.user.college,
  9. major: state => state.user.major,
  10. routers: state => state.permission.routers,
  11. addRouters: state => state.permission.addRouters
  12. }
  13. export default getters
  1. // store/permission.js
  2. import { asyncRouterMap, constantRoutes } from '@/router'
  3. function hasPermission(roles, route) {
  4. if (route.meta && route.meta.role) {
  5. return roles.some(role => route.meta.role.indexOf(role) >= 0)
  6. } else {
  7. return true
  8. }
  9. }
  10. const state = {
  11. routers: constantRoutes,
  12. addRouters: []
  13. }
  14. const mutations = {
  15. SET_ROUTERS: (state, routers) => {
  16. state.addRouters = routers
  17. state.routers = constantRoutes.concat(routers)
  18. }
  19. }
  20. const actions = {
  21. GenerateRoutes({ commit }, data) {
  22. return new Promise(resolve => {
  23. const roles = data
  24. const accessedRouters = asyncRouterMap.filter(v => {
  25. if (roles.indexOf('admin') >= 0) return true
  26. if (hasPermission(roles, v)) {
  27. if (v.children && v.children.length > 0) {
  28. v.children = v.children.filter(child => {
  29. if (hasPermission(roles, child)) {
  30. return child
  31. }
  32. return false
  33. })
  34. return v
  35. } else {
  36. return v
  37. }
  38. }
  39. return false
  40. })
  41. commit('SET_ROUTERS', accessedRouters)
  42. resolve()
  43. })
  44. }
  45. }
  46. export default {
  47. namespaced: true,
  48. state,
  49. mutations,
  50. actions
  51. }

6、动态菜单和路由

  1. // src/permission.js
  2. import router from './router'
  3. import store from './store'
  4. import { Message } from 'element-ui'
  5. import NProgress from 'nprogress' // progress bar
  6. import 'nprogress/nprogress.css' // progress bar style
  7. import { getToken } from '@/utils/auth' // get token from cookie
  8. import getPageTitle from '@/utils/get-page-title'
  9. NProgress.configure({ showSpinner: false }) // NProgress Configuration
  10. const whiteList = ['/login'] // no redirect whitelist
  11. // 全局钩子函数
  12. router.beforeEach(async(to, from, next) => {
  13. // start progress bar
  14. NProgress.start()
  15. // set page title
  16. document.title = getPageTitle(to.meta.title)
  17. // determine whether the user has logged in
  18. const hasToken = getToken()
  19. if (hasToken) {
  20. if (to.path === '/login') {
  21. // if is logged in, redirect to the home page
  22. next({ path: '/' })
  23. NProgress.done()
  24. } else {
  25. const hasGetUserInfo = store.getters.name
  26. if (hasGetUserInfo) {
  27. next()
  28. } else {
  29. try {
  30. // get user info
  31. await store.dispatch('user/getInfo').then(res => {
  32. // 根据权限动态生成路由
  33. const { roles } = res
  34. store.dispatch('permission/GenerateRoutes', roles).then(() => {
  35. router.addRoutes(store.getters.addRouters) // 根据roles动态添加可访问路由表
  36. next({ ...to, replace: true }) // hack方法 确保addRoutes已完成
  37. })
  38. })
  39. next()
  40. } catch (error) {
  41. // remove token and go to login page to re-login
  42. await store.dispatch('user/resetToken')
  43. Message.error(error || 'Has Error')
  44. next(`/login?redirect=${to.path}`)
  45. NProgress.done()
  46. }
  47. }
  48. }
  49. } else {
  50. /* has no token*/
  51. if (whiteList.indexOf(to.path) !== -1) {
  52. // in the free login whitelist, go directly
  53. next()
  54. } else {
  55. // other pages that do not have permission to access are redirected to the login page.
  56. next(`/login?redirect=${to.path}`)
  57. NProgress.done()
  58. }
  59. }
  60. })
  61. router.afterEach(() => {
  62. // finish progress bar
  63. NProgress.done()
  64. })
  1. // src/layout/components/Sidebar/index.vue
  2. computed: {
  3. ...mapGetters([
  4. 'sidebar',
  5. 'routers'
  6. ])}
  7. <sidebar-item v-for="route in routers" :key="route.path" :item="route" :base-path="route.path" />

7、跨域

dev下跨域

  1. # just a flag
  2. ENV = 'development'
  3. # base api
  4. VUE_APP_BASE_API = '/api'
  1. devServer: {
  2. port: port,
  3. open: true,
  4. overlay: {
  5. warnings: false,
  6. errors: true
  7. },
  8. proxy: {
  9. '/api': {
  10. // 这里就改成本地的接口路径
  11. target: 'http://localhost:8081',
  12. changeOrigin: true,
  13. pathRewrite: {
  14. '^/api': ''
  15. }
  16. }
  17. }
  18. // before: require('./mock/mock-server.js')
  19. }

prod下的跨域

使用nginx反向代理

  1. server
  2. {
  3. listen 8088; # nginx监听的端口
  4. server_name yuyue;
  5. location / {
  6. root /home/william/yuyue_server/dist/; # 托管dist文件夹
  7. index index.html index.htm;
  8. try_files $uri $uri/ /index.html;
  9. }
  10. location /api/ {
  11. proxy_pass http://1.1.1.1:8081/; # 后端服务器的地址 注意结尾的 /
  12. }
  13. #error_page 404 /404.html;
  14. # redirect server error pages to the static page /50x.html
  15. #
  16. error_page 500 502 503 504 /50x.html;
  17. location = /50x.html {
  18. root html;
  19. }
  20. }
  1. # just a flag
  2. ENV = 'production'
  3. # base api nginx的地址和服务的监听端口
  4. VUE_APP_BASE_API = 'http://1.1.1.1:8088/api'

ge 404 /404.html;

  1. # redirect server error pages to the static page /50x.html
  2. #
  3. error_page 500 502 503 504 /50x.html;
  4. location = /50x.html {
  5. root html;
  6. }
  7. }
  1. ```ini
  2. # just a flag
  3. ENV = 'production'
  4. # base api nginx的地址和服务的监听端口
  5. VUE_APP_BASE_API = 'http://1.1.1.1:8088/api'