简单记录一下使用vue-element-admin

后台项目我采用的是vue-element-admin后台模板,我们下载下来做下改造。

1.关闭自带的mock

   1-1 去除main.js

1 // if (process.env.NODE_ENV === 'production') {
2 //   const { mockXHR } = require('../mock')
3 //   mockXHR()
4 // }

 1-2 vue.config.js加入

 

 1   devServer: {
 2     port: 5001,
 3     open: true,
 4     overlay: {
 5       warnings: false,
 6       errors: true
 7     },
 8     proxy: {
 9       '/': {
10         target: `xxx.com`,//要代理的地址
11         changeOrigin: true,
12         pathRewrite: {
13           '^/': ''//代理后的地址
14         }
15       }
16     },
17     after: require('./mock/mock-server.js')
18   }

使用的话,正常使用比如  '/getList'

2.路由修改

  1 import Vue from 'vue'
  2 import Router from 'vue-router'
  3 
  4 Vue.use(Router)
  5 
  6 /* Layout */
  7 import Layout from '@/layout'
  8 //固定的路由
  9 export const constantRoutes = [
 10   {
 11     path: '/redirect',
 12     component: Layout,
 13     hidden: true,
 14     children: [
 15       {
 16         path: '/redirect/:path(.*)',
 17         component: () => import('@/views/redirect/index')
 18       }
 19     ]
 20   },
 21   {
 22     path: '/login',
 23     component: () => import('@/views/login/index'),
 24     hidden: true
 25   },
 26   {
 27     path: '/auth-redirect',
 28     component: () => import('@/views/login/auth-redirect'),
 29     hidden: true
 30   },
 31   {
 32     path: '/404',
 33     component: () => import('@/views/error-page/404'),
 34     hidden: true
 35   },
 36   {
 37     path: '/401',
 38     component: () => import('@/views/error-page/401'),
 39     hidden: true
 40   },
 41   {
 42     path: '/',
 43     component: Layout,
 44     redirect: '/dashboard',
 45     children: [
 46       {
 47         path: 'dashboard',
 48         component: () => import('@/views/dashboard/index'),
 49         name: 'Dashboard',
 50         meta: { title: 'Dashboard', icon: 'dashboard', affix: true }
 51       }
 52     ]
 53   }
 54 ]
 55 
 56 //动态路由不确定
 57 export const asyncRoutes = [
 58   {
 59     path:'/data',
 60     component:Layout,
 61     redirect:'/data/create',
 62     meta:{title:'数据管理',icon:'documentation',roles:['admin','editor']},
 63     children:[
 64       {
 65         path:'/data/create',
 66         component:()=>import('@/views/data/create'),
 67         meta: { title: '添加数据', icon: 'edit', roles: ['admin'] }
 68       },
 69       {
 70         path:'/data/edit',
 71         component:()=>import('@/views/data/edit'),
 72         hidden:true,//隐藏不在侧边栏显示
 73         meta: { title: '编辑数据', icon: 'edit', roles: ['admin'],activeMenu:'/data/list' }
 74         //activeMenu当路由为'/data/edit',侧边栏高亮对应'/data/list'
 75       },
 76       {
 77         path:'/data/list',
 78         component:()=>import('@/views/data/list'),
 79         meta: { title: '数据列表', icon: 'list', roles: ['editor'] }
 80       }
 81     ]
 82   },
 83   //都匹配不到跳转404页面
 84   { path: '*', redirect: '/404', hidden: true }
 85 ]
 86 
 87 const createRouter = () => new Router({
 88   // mode: 'history', // require service support
 89   //切换路由滚到头部
 90   scrollBehavior: () => ({ y: 0 }),
 91   routes: constantRoutes
 92 })
 93 
 94 const router = createRouter()
 95 export function resetRouter() {
 96   const newRouter = createRouter()
 97   router.matcher = newRouter.matcher // reset router
 98 }
 99 
100 export default router
View Code

3.权限判断

首先判断是否存在token:

没有token判断要去的页面是否需要token,不需要直接跳转,需要跳转登录页面并且带上要去的页面。

有token的时候如果要去登录页面,直接跳转主页面。不是登录页面的话,在判断是否存在用户信息,通过用户信息生成动态路由

 1 import router from './router'
 2 import store from './store'
 3 import { Message } from 'element-ui'
 4 import NProgress from 'nprogress' // progress bar
 5 import 'nprogress/nprogress.css' // progress bar style
 6 import { getToken } from '@/utils/auth' // get token from cookie
 7 import getPageTitle from '@/utils/get-page-title'
 8 
 9 NProgress.configure({ showSpinner: false })
10 //白名单不需要token
11 const whiteList = ['/login', '/auth-redirect'] 
12 
13 router.beforeEach(async(to, from, next) => {
14   NProgress.start()
15   //修改顶部名字
16   document.title = getPageTitle(to.meta.title)
17   //获取token
18   const hasToken = getToken()
19 
20   if (hasToken) {
21     if (to.path === '/login') {
22       //如果有token且要去的页面是登录页面,直接跳到主页面
23       next({ path: '/' })
24       NProgress.done() 
25     } else {
26       const hasRoles = store.getters.roles && store.getters.roles.length > 0
27       //判断是否拥有用户信息
28       if (hasRoles) {
29         next()
30       } else {
31         try {
32           //获取用户信息
33           const { roles } = await store.dispatch('user/getInfo')
34           //根据用户动态生成路由
35           const accessRoutes = await store.dispatch('permission/generateRoutes', roles)
36           router.addRoutes(accessRoutes)
37           next({ ...to, replace: true })
38         } catch (error) {
39           await store.dispatch('user/resetToken')
40           Message.error(error || 'Has Error')
41           next(`/login?redirect=${to.path}`)
42           NProgress.done()
43         }
44       }
45     }
46   } else {
47     //在白名单直接跳转
48     if (whiteList.indexOf(to.path) !== -1) {
49       next()
50     } else {
51       //跳转到登录页面,并记录要去的路由
52       next(`/login?redirect=${to.path}`)
53       NProgress.done()
54     }
55   }
56 })
57 
58 router.afterEach(() => {
59   NProgress.done()
60 })
View Code

 前面说没有token前往登录页面,现在分析登录页面。

 1   watch: {
 2     //监听路由变化获取路由参数,登录后需要跳转的页面和参数
 3     $route: {
 4       handler: function(route) {
 5         const query = route.query
 6         if (query) {
 7           this.redirect = query.redirect
 8           this.otherQuery = this.getOtherQuery(query)
 9         }
10       },
11       immediate: true
12     }
13   },

其中getOtherQuery为页面所带参数

1  getOtherQuery(query) {
2       return Object.keys(query).reduce((acc, cur) => {
3         if (cur !== 'redirect') {
4           acc[cur] = query[cur]
5         }
6         return acc
7       }, {})
8     }
1 this.$store.dispatch('user/login', this.loginForm)
2    .then(() => {
3         //登录成功跳转到输入路由,携带参数
4         this.$router.push({ path: this.redirect || '/', query: this.otherQuery })
5         this.loading = false
6      })
7       .catch(() => {
8          this.loading = false
9     })

这里登录触发 dispatch('user/login'),来看一下这里面发生了什么

1  commit('SET_TOKEN', data.token)
2  setToken(data.token)
3 //登录获取信息把token存起来
 
刚才permission中
const { roles } = await store.dispatch('user/getInfo')
 //getInfo通过存起来的token获取用户信息
//根据用户动态生成路由 const accessRoutes = await store.dispatch('permission/generateRoutes', roles)//获取到action动态生成的路由 router.addRoutes(accessRoutes)

权限判断中

 1   generateRoutes({ commit }, roles) {
 2     return new Promise(resolve => {
 3       let accessedRoutes
 4       //用户是admin拥有所有权
 5       if (roles.includes('admin')) {
 6         accessedRoutes = asyncRoutes || []
 7       } else {
 8         //不是超级管理员进入filterAsyncRoutes函数判断
 9         accessedRoutes = filterAsyncRoutes(asyncRoutes, roles)
10        }
11       commit('SET_ROUTES', accessedRoutes)//把动态生成路由存起来
12       resolve(accessedRoutes)//返回生成动态路由
13     })
14   }
 1 export function filterAsyncRoutes(routes, roles) {
 2   const res = []
 3 
 4   routes.forEach(route => {
 5     const tmp = { ...route }
 6     debugger
 7     if (hasPermission(roles, tmp)) {
 8       if (tmp.children) {
 9         tmp.children = filterAsyncRoutes(tmp.children, roles)
10       }
11       //满足条件存起来
12       res.push(tmp)
13     }
14   })
15 
16   return res
17 }
 1 function hasPermission(roles, route) {
 2   //判断路由是否存在与用户相同权限将会返回true
 3   //路由不需要角色判断也会返回true
 4 
 5   if (route.meta && route.meta.roles) {
 6     return roles.some(role => route.meta.roles.includes(role))
 7   } else {
 8     return true
 9   }
10 }

 

posted on 2020-07-30 16:13  小白学前端  阅读(894)  评论(0编辑  收藏  举报