vue權限與路由攔截

流程思路

通用路由+路由表-->后端返回路由權限數據
數據與路由表相互映射 --> 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
})
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。