VUE权限管理直接复制即可

本文介绍了如何在Vue应用中实现权限控制和路由配置,包括使用`asyncRoutes`处理需要权限的页面,通过`store`管理用户登录状态和权限列表,并结合`loopRoles`和`loopCheck`函数实现动态路由权限匹配。
摘要由CSDN通过智能技术生成
  1. Router

// 都可以见的
export const constantRoutes = [
  {
    path: '/login',
    component: () => import('@/views/login/index'),
    hidden: true
  },

  {
    path: '/404',
    component: () => import('@/views/404'),
    hidden: true
  },
]


// 需要配置权限的
export const asyncRoutes = [
  {
    path: '/',
    component: Layout,
    redirect: '/home',
    children: [{
      path: 'home',
      name: 'Home',
      component: () => import('@/views/home/index'),
      meta: { title: '首页', icon: 'el-icon-s-home' }
    }]
  },]


// 下面合并处理
const createRouter = () => new Router({
  // mode: 'history', // require service support
  scrollBehavior: () => ({ y: 0 }),
  routes: constantRoutes.concat(asyncRoutes)
})

const router = createRouter()
// 路由钩子处理
router.beforeEach((to, from, next) => {
  if (!to.path === '/login' && store.getters.permList.length > 0) {
    if (to.meta && to.meta.roles) {
      let flag = false;
      for (let index = 0; index < to.meta.roles.length; index++) {
        const element = to.meta.roles[index];
        if (store.getters.permList.indexOf(element) > -1) {
          flag = true;
        }
      }
      if (!flag) return router.push({
        path: "/404",
      })
    }
    next();
  }
  next();
});

// 注销登录 先清除token,然后刷新页面 调下面这个接口
// Detail see: https://github.com/vuejs/vue-router/issues/1234#issuecomment-357941465
export function resetRouter() {
  const newRouter = createRouter()
  router.matcher = newRouter.matcher // reset router
}


 2. store  VUEX的处理
   // user logout  登录
   login({ commit },userInfo) {
    const { username,password } = userInfo
    return new Promise((resolve,reject) => {
    // qs序列化
      login(qs.stringify({ username: username.trim(),password: password })).then(response => {
        if (response.data.code === "1") {
          Message({
            message: response.data.message || '登陆成功',
            type: 'success',
            duration: 5 * 1000
          })
          const { data } = response;
          commit('SET_TOKEN',data.data);
          // cookie本地储存token
          setToken(data.data);
        } else if (response.data.code !== "1") {
          Message({
            message: response.data.message || 'Error',
            type: 'error',
            duration: 5 * 1000
          })
        }
        resolve(response)
      }).catch(error => {
        reject(error)
      })
    })
  },

 SET_TOKEN: (state,token) => {
    state.token = token
},


// user logout  退出
  logout({ commit,state }) {
    return new Promise((resolve,reject) => {
      logout(state.token).then(() => {
        removeToken() // must remove  token  first
        resetRouter()
        commit('RESET_STATE')
        resolve()
      }).catch(error => {
        reject(error)
      })
    })
  },
 RESET_STATE: (state) => {
    Object.assign(state,getDefaultState())
 },


 3. permission的处理
 import router from './router'
import store from './store'
import {
  Message
} from 'element-ui'
import NProgress from 'nprogress' // progress bar
import 'nprogress/nprogress.css' // progress bar style
import {
  getToken
} from '@/utils/auth' // get token from cookie
import getPageTitle from '@/utils/get-page-title'


//这里
import {
  deepFn,
  loopCheck,
  loopRoles
} from '@/utils'
import {
  constantRoutes,
  asyncRoutes
} from "@/router";
NProgress.configure({
  showSpinner: false
}) // NProgress Configuration

const whiteList = ['/login'] // no redirect whitelist
// if (process.env.NODE_ENV !== 'development') {
router.beforeEach(async (to, from, next) => {
  // start progress bar
  NProgress.start()

  // set page title
  document.title = getPageTitle(to.meta.title)

  // determine whether the user has logged in
  const hasToken = getToken()

  if (hasToken) {
    if (to.path === '/login') {
      // if is logged in, redirect to the home page
      next({
        path: '/'
      })
      NProgress.done()
    } else {
      const hasGetUserInfo = store.getters.name
      if (hasGetUserInfo) {
        next()
      } else {
        try {
          // get user info
          await store.dispatch('user/getInfo')


          // 获取个人信息路由列表
          // 做过处理得到权限路由数组
          const permList = store.getters.permList;
          // console.log(permList,'permList');

          // 配置路由权限的对象
          let asyncRoutesRoutes = asyncRoutes;

          // 取出路由对象
          /* 
          {公文管理: Array(4), 发文管理: Array(1), 收文管理: Array(1), 呈批呈阅: Array(1), 会议管理: Array(1), …}
          */
          let rr = loopRoles(asyncRoutesRoutes);
          console.log(rr, "1111");


          //  匹配的路由和后台返回路由匹配形成数组
          let mm = loopCheck(asyncRoutesRoutes, permList, rr);
          console.log(mm, "2222");
          

          //  可以拿到初始化时配置的路由规则
          router.options.routes = constantRoutes.concat(mm);
          await store.dispatch('user/setRouters', constantRoutes.concat(mm))
          next()
        } catch (error) {
          // remove token and go to login page to re-login
          await store.dispatch('user/resetToken')
          Message.error(error || 'Has Error')
          next(`/login?redirect=${to.path}`)
          NProgress.done()
        }
      }
    }
  } else {
    /* has no token*/

    if (whiteList.indexOf(to.path) !== -1) {
      // in the free login whitelist, go directly
      next()
    } else {
      // other pages that do not have permission to access are redirected to the login page.
      next(`/login?redirect=${to.path}`)
      NProgress.done()
    }
  }
})
// }

router.afterEach(() => {
  // finish progress bar
  NProgress.done()
})



 4. utils/index.js
// lodash插件
import _ from 'lodash'

 // 两者都是深拷贝获取键值对
 export function loopRoles(data) {
  let listRoles = {};
  for (let index = 0; index < data.length; index++) {
    let item = data[index];

    let roles = _.get(item,'meta.roles');
    let title = _.get(item,'meta.title');

    let r = [];
    if (roles && title) {
      listRoles[title] = roles;
    }

    if (item.children && item.children.length > 0) {
      let _m = loopRoles(item.children);
      for (let i in _m) {
        listRoles[title] = _.concat(listRoles[title],_m[i]);
      }

      listRoles = { ...listRoles,..._m }

    };
    // console.log('deepFn', item.meta.title);
  }
  return listRoles;
}

export function loopCheck(data,routers,rr) {
  let menu = [];
  for (let index = 0; index < data.length; index++) {
    let item = data[index];
    // console.log('deepFn', item.meta.title);
    let roles = _.get(item,'meta.roles');
    let title = _.get(item,'meta.title');
    let rl = title in rr ? rr[title] : [];
    let ie = _.cloneDeep(item);
    ie.children = [];
    if (roles) {
      // console.log('deepFn', item.meta);
      let iarr = _.intersection(roles,routers);
      if (iarr.length > 0) {
        menu.push(ie);
      } else {
        let iarr = _.intersection(rl,routers);
        // console.log(title, rl, iarr);
        if (iarr.length > 0) {
          menu.push(ie);
        }
      }
    } else {
      menu.push(ie);
    }
    if (item.children && item.children.length > 0) {
      let _m = loopCheck(item.children,routers,rr);
      if (_m.length > 0) {
        ie.children = _.concat(ie.children,_m);
      }
    };
    if (ie.children.length == 0) {
      delete ie.children;
    }
  }
  return menu;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值