美文网首页
vue权限与路由拦截

vue权限与路由拦截

作者: 年过古稀的Coder | 来源:发表于2019-12-18 23:05 被阅读0次

    流程思路

    通用路由+路由表-->后端返回路由权限数据
    数据与路由表相互映射 --> addRoutes
    addRoutes --> 全局路由拦截非权限内路由地址
    f5刷新页面重新请求路由表

    直接上代码

    ++router/index.js++

    import Vue from 'vue'
    import Router from 'vue-router'
    //挂载到vue上
    Vue.use(Router)
    // 通用路由
    export const constantRouterMap = [
      { path: '/login', component: () => import('@/views/login/index'), hidden: true },
      { path: '/404', component: () => import('@/views/404'), hidden: true },
    
      {
        path: '',
        component: Layout,
        redirect: 'dashboard',
        children: [{
          path: 'dashboard',
          component: () => import('@/views/dashboard/index'),
          name: 'dashboard',
          meta: { title: '首页', icon: 'dashboard' }
        }]
      }
    ]
    export default new Router({
      // mode: 'history', //后端支持可开
      scrollBehavior: () => ({ y: 0 }), //切换路由时滚动到顶部
      routes: constantRouterMap //默认使用通用路由
    })
    
    //路由表,用于跟后端返回数据进行映射
    //component属性的值为import进来的模块,如果不这样得做二次映射
    export const newRouters = {
      "routes": [
        {
          "path": "/user",
          "component": Layout,
          "redirect": "/user/userList",
          "name": "User",
          "meta": { "title": "用户系统", "icon": "user" },
          "alwaysShow": true,
          "children": [
            {
              "path": "userList",
              "name": "UserList",
              "component": () => import('@/views/UserList/index'),
              "meta": { "title": "用户列表", "icon": "user" }
            }
          ]
        },
        {
          "path": "/webManager",
          "component": Layout,
          "redirect": "/webManager/home",
          "name": "WebManager",
          "meta": { "title": "网站管理", "icon": "money" },
          "alwaysShow": true,
          "children": [
            {
              "path": "home",
              "name": "Home",
              "component": () => import('@/views/WebManager/Home'),
              "meta": { "title": "网站首页管理", "icon": "money" }
            },
            {
              "path": "banner",
              "name": "Banner",
              "component": () => import('@/views/WebManager/Banner'),
              "meta": { "title": "banner管理", "icon": "money", "parents": [ {  "meta": { "title": "网站首页管理" }, "path": "/webManager/home" } ] },
              "hidden": true
            },
            {
              "path": "news",
              "name": "News",
              "component": () => import('@/views/WebManager/News'),
              "meta": { "title": "资讯管理", "icon": "money", "parents": [ {  "meta": { "title": "网站首页管理" }, "path": "/webManager/home" } ] },
              "hidden": true
            }
          ]
        },
        { "path": "*", "redirect": "/404", "hidden": true }
      ]
    }
    

    ++store/modules/user.js++

    // 请求权限(路由)数据接口
    import { newRoutersOnline } from '@/api/login'
    import router, { newRouters } from '@/router/index'
    
    // 路由映射函数
    function recursionRouters(userRouter = [], newRouters = []) {
      let addRouter = []
      userRouter.forEach((userRouterItem, index) => {
        newRouters.forEach((newRoutersItem, index) => {
          if (newRoutersItem.path === userRouterItem.path) {
            const item = newRoutersItem
            if (userRouterItem.children) {
              const children = recursionRouters(userRouterItem.children, newRoutersItem.children)
              if (children.length) {
                item.children = children
              }
            }
            addRouter.push(item)
          }
        })
      })
      return addRouter
    }
    
    const user = {
      state: {
        routes: []
      },
      mutations: {
        SET_ROUTES: (state, roles) => {
          state.routes = roles
        }
      },
      actions: {
        SetRoutes({ commit, state }) {
          return new Promise((resolve, reject) => {
            newRoutersOnline().then(res => {
              const newRoutes = recursionRouters(res.data, newRouters.routes)
              commit('SET_ROUTES', [...router.options.routes, ...newRoutes])
              resolve(newRoutes)
            }).catch(error => {
              reject(error)
            })
          })
        },
      }
    

    ++permission.js++//全局路由拦截配置文件

    ++utils/auth++

    import Cookies from 'js-cookie'
    
    const TokenKey = 'Admin-Token'
    
    export function getToken() {
      return Cookies.get(TokenKey)
    }
    
    import router from './router'
    import store from './store'
    import NProgress from 'nprogress' // Progress 进度条
    import 'nprogress/nprogress.css'// Progress 进度条样式
    import { getToken } from '@/utils/auth' // 验权
    
    const whiteList = ['/login', '/404'] // 不重定向白名单
    
    router.beforeEach((to, from, next) => {
      if (getToken()) {
        if (to.path === '/login') {
          next({ path: '/' })
          NProgress.done()
        } else {
          //如果在登录状态,但是路由表丢失的情况下,调用store的请求路由表(适用于刷新页面后丢失store数据)
          if (store.getters.routes.length === 0) {
            store.dispatch('SetRoutes').then(res => {
              //addRoutes应该不用解释了吧。。。
              router.addRoutes(res)
              next({ ...to, replace: true })
            }).catch((err) => {
              store.dispatch('FedLogOut').then(() => {
                Message.error(err || '登陆失效,请重新登陆')
                next({ path: '/' })
              })
            })
          } else {
            next()
          }
        }
      } else {
        if (whiteList.indexOf(to.path) !== -1) {
          next()
        } else {
          next(`/login?redirect=${to.path}`) // 否则全部重定向到登录页
          NProgress.done()
        }
      }
    }
    
    router.afterEach(() => {
      NProgress.done() // 结束Progress
    })
    

    相关文章

      网友评论

          本文标题:vue权限与路由拦截

          本文链接:https://www.haomeiwen.com/subject/gjypnctx.html