Vue 权限路由实现菜单列表

需求:根据登录用户的权限,显示不同导航菜单也,同时操作不同的界面。

(1)首先在本地配置好【所有页面】下的路由地址,如下:

import Vue from 'vue';
import Router from 'vue-router';
import User from '@/views/system/user';

Vue.use(Router);

let constRouter = [
  { path: '/', redirect: '/login' },
  { path: '/login', component: Login },
  { path: '/', component: Home, children: [{ path: '/user', component: User, meta: { title: '用户管理' }}, ...]},
  { path: '*', redirect: '/404' }
]

let router = new Router({
  routes: constRouter
})

export default router

(2)使用钩子函数 router.beforeEach 对路由进行权限跳转。

router.beforeEach((to, from, next) => {
  if(to.path == '/login'){
    localStorage.clear()
  }
  let user = localStorage.getItem('USER_TOKEN');
  if(!user && to.path != '/login'){
    next({ path: '/login' });
  }else {
    next()
  }
})

(3)通过接口获取菜单列表信息

getMenuList (_callback) {
  let data = JSON.parse(localStorage.getItem('USER'));
  let user = data.username
  this.$get(`menu/${user}`).then(r => {
    localStorage.setItem('USER_ROUTER', JSON.stringify(r.data[0].children))
    let filterResult = []
    if (r.data[0].children.length) {
      r.data[0].children.forEach(item => {
        if (item.name === '系统主页' || item.name === '个人中心') {
          return
        } else {
          filterResult.push(item)
        }
      })
    }
    this.routerPath = getAllLeaf(filterResult)
    _callback(this.routerPath)
  }).catch(err => {
    console.log(err)
  })
},

返回接口信息:

(4)在登录成功之后,使用 getMenuList 回调函数获取用户菜单栏

this.getMenuList(_callback => {
  if (this.routerPath.length) {
    this.$router.push(this.routerPath[0])
  } else {
    this.$message.error('暂无权限, 请联系管理员')
  }
}) 

(5)截取树状结构的叶子节点信息,决定用户登录之后进入那个页面。这里使用递归函数获取到所有叶子节点,返回数组信息,将数组中的第一个节点信息,作为用户登录之后进入的页面。

// tree 结构数据的叶子节点
export function getAllLeaf (data) {
  let result = []
  function getLeaf (data) {
    data.forEach(item => {
      if (!item.children) {
        result.push(item.path)
      } else {
        getLeaf(item.children)
      }
    })
  }
  getLeaf(data)
  return result
}

(6)如何渲染左边菜单栏的数据呢?这里主要最多三级菜单的处理。

<div class="sidebar">
  <el-menu
    class="sidebar-el-menu"
    :default-active="$route.path"
    :collapse="collapse"
    background-color="#324157"
    text-color="#bfcbd9"
    active-text-color="#20a0ff"
    unique-opened
    router
  >
    <template v-for="(item, index) in items">
      <template v-if="item.children">
        <el-submenu :index='index+""' :key="index">
          <template slot="title">
            <i :class="item.icon"></i>
            <span slot="title">{{ item.name }}</span>
          </template>
          <template v-for="subItem in item.children">
            <el-submenu v-if="subItem.children" :index="subItem.path" :key="subItem.path">
              <template slot="title">{{ subItem.name }}</template>
              <el-menu-item 
                v-for="(threeItem,i) in subItem.children"
                :key="i"
                :index="threeItem.path">
                {{ threeItem.name }}
              </el-menu-item>               
            </el-submenu>
            <el-menu-item v-else :index="subItem.path" :key="subItem.path">{{ subItem.name }}</el-menu-item>
          </template>
        </el-submenu>
      </template>
      <template v-else>
        <el-menu-item :index="item.path" :key="item.path">
          <i :class="item.icon"></i>
          <span slot="title">{{ item.name }}</span>
        </el-menu-item>
      </template>
    </template>
  </el-menu>
</div>

如果有更好的意见或者不当之处,希望大家发表您宝贵的想法,谢谢

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值