美文网首页
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