vue前端实现左侧栏权限

本文详细介绍了Vue.js应用中路由的配置方法,包括基本路由、嵌套路由和权限管理。通过引入vue-router库,实现动态加载路由并根据用户角色过滤路由。同时,展示了如何在store模块中处理权限判断,实现不同角色访问不同页面的功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

router/index.vue

import Vue from 'vue'
import Router from 'vue-router'

Vue.use(Router)

/* Layout */
import Layout from '@/layout'

/* Router Modules */
// import componentsRouter from './modules/components'
// import chartsRouter from './modules/charts'
// import tableRouter from './modules/table'
// import nestedRouter from './modules/nested'

/**
 * Note: sub-menu only appear when route children.length >= 1
 * Detail see: https://panjiachen.github.io/vue-element-admin-site/guide/essentials/router-and-nav.html
 *
 * hidden: true                   if set true, item will not show in the sidebar(default is false)
 * alwaysShow: true               if set true, will always show the root menu
 *                                if not set alwaysShow, when item has more than one children route,
 *                                it will becomes nested mode, otherwise not show the root menu
 * redirect: noRedirect           if set noRedirect will no redirect in the breadcrumb
 * name:'router-name'             the name is used by <keep-alive> (must set!!!)
 * meta : {
    roles: ['admin','editor']    control the page roles (you can set multiple roles)
    title: 'title'               the name show in sidebar and breadcrumb (recommend set)
    icon: 'svg-name'/'el-icon-x' the icon show in the sidebar
    noCache: true                if set true, the page will no be cached(default is false)
    affix: true                  if set true, the tag will affix in the tags-view
    breadcrumb: false            if set false, the item will hidden in breadcrumb(default is true)
    activeMenu: '/example/list'  if set path, the sidebar will highlight the path you set
  }
 */

/**
 * constantRoutes
 * a base page that does not have permission requirements
 * all roles can be accessed
 */
/**
 * 单层路由 children只有一个时候,侧边导航只会显示一个,假如children 有多个,才会有多个
 * meta==>title key代表的是侧边栏与面包屑导航的标题  多层路由 子集以及父级都必有带有 meta
 * 单层路由 父级可以不必有meta
 *
 * children只有一个时候, 单层路由可以没有name,多个children时候name需要同时有,  同上 使用英文 不能使用汉字
 *  单层实例
 *     {
 *        path:'/',
 *        component: Layout,
 *        redirect: '/dashboard',
 *        children:[
 *          path:'dashboard'
 *          component: () => import('@/views/dashboard/index'),
 *          name: 'Dashboard',
 *          meta: { title: '首页', icon: 'dashboard' }
 *        ]
 *     }
 *
 *   多层实例
 *     {
 *        path:'/other',
 *        component: Layout,
 *        redirect: '/other/page1',
 *        meta: { title: '其它', icon: 'dashboard', affix: true },
 *        name:'others'
 *        children:[
 *             {
 *               path: 'page1',
 *               component: () => import('@/views/dashboard/index'),
 *               name: 'othersPage1',
 *               meta: { title: '页面1', icon: 'dashboard' }
 *             },
 *             {
 *               path: 'page2',
 *               component: () => import('@/views/dashboard/index'),
 *               name: 'othersPage2',
 *               meta: { title: '页面2', icon: 'dashboard' }
 *             }
 *        ]
 *     }
 *
 *
 */
export const constantRoutes = [{
		path: '/redirect',
		component: Layout,
		hidden: true,
		children: [{
			path: '/redirect/:path(.*)',
			component: () => import('@/views/redirect/index')
		}]
	},
	{
		path: '/login',
		component: () => import('@/views/login/index'),
		hidden: true
	},

	
	{
		path: '/auth-redirect',
		component: () => import('@/views/login/auth-redirect'),
		hidden: true
	},

	{
		path: '/404',
		component: () => import('@/views/error-page/404'),
		hidden: true
	},
	{
		path: '/401',
		component: () => import('@/views/error-page/401'),
		hidden: true
	},
	{
		path: '/',
		component: Layout,
		redirect: '/index',
		meta: {
			title: '项目列表',
			icon: 'el-icon-tickets',
			Kid:5
		},
		name: 'index',
		children: [{
				path: 'index',
				component: () => import('@/views/index/index'),
				name: 'index',
				meta: {
					title: '项目管理',
					icon: '',
					Kid:6,Fid:5
				}
			},
			{
				path: 'statistics',
				component: () => import('@/views/statistics/statistics'),
				name: 'indexPage',
				meta: {
					title: '数据统计',
					icon: '',
					Kid:7,Fid:5
				}
			},{
				path: 'projectmore',
				component: () => import('@/views/projectmore/projectmore'),
				hidden: true,
				meta: {
					title: '项目详情',
					icon: '',
					Kid:8,Fid:5
				}
			
			},
		]
	},
	{
		path: '/summary',
		component: Layout,
		redirect: '/summary',
		meta: {
			title: '汇总计算',
			icon: 'el-icon-data-analysis',
		},
		name: 'summary',
		children: [
			{
				path: 'summary',
				component: () => import('@/views/summary/summary'),
				name: 'summary',
				meta: {
					title: '汇总计算',
					icon: '',
				}
			}
		]
	},

]

/**
 * asyncRoutes
 * the routes that need to be dynamically loaded based on user roles
 */
export const asyncRoutes = [

	// 404 page must be placed at the end !!!
	// {
	// 	path: '*',
	// 	redirect: '/404',
	// 	hidden: true
	// }
	{
		path: '/UserList',
		component: Layout,
		redirect: '/UserList',
		meta: {
			icon: 'el-icon-user',
			Kid:1,
		},
		name: 'UserList',
		children: [
			{
				path: 'UserList',
				component: () => import('@/views/UserList/UserList'),
				name: 'UserList',
				meta: {
					title: '用户管理',
					Kid:2,Fid:1
				}
			}
		]
	},
	{
		path: '/Dictionary',
		component: Layout,
		redirect: '/Dictionary',
		meta: {
			icon: 'el-icon-notebook-2',
			Kid:77,
		},
		name: 'Dictionary',
		children: [
			{
				path: 'Dictionary',
				component: () => import('@/views/Dictionary/Dictionary'),
				name: 'Dictionary',
				meta: {
					title: '字典管理',
					Kid:78,Fid:77
				}
			}
		]
	},
	
]

const createRouter = () => new Router({
	// mode: 'history', // require service support
	scrollBehavior: () => ({
		y: 0
	}),
	routes: constantRoutes
})

const router = createRouter()

// Detail see: https://github.com/vuejs/vue-router/issues/1234#issuecomment-357941465
export function resetRouter() {
	const newRouter = createRouter()
	router.matcher = newRouter.matcher // reset router
}

export default router

store/modules/permission.js

import { asyncRoutes, constantRoutes } from '@/router'

/**
 * Use meta.role to determine if the current user has permission
 * @param roles
 * @param route
 */
function hasPermission(roles, route) {
  if (route.meta && route.meta.roles) {
    return roles.some(role => route.meta.roles.includes(role))
  } else {
    return true
  }
}

/**
 * Filter asynchronous routing tables by recursion
 * @param routes asyncRoutes
 * @param roles
 */
export function filterAsyncRoutes(routes, roles) {
  const res = []

  routes.forEach(route => {
    const tmp = { ...route }
    if (hasPermission(roles, tmp)) {
      if (tmp.children) {
        tmp.children = filterAsyncRoutes(tmp.children, roles)
      }
      res.push(tmp)
    }
  })

  return res
}

const state = {
  routes: [],
  addRoutes: []
}

const mutations = {
  SET_ROUTES: (state, routes) => {
    state.addRoutes = routes
    state.routes = constantRoutes.concat(routes)
  }
}

const actions = {
  generateRoutes({ commit }, roles) {
    return new Promise(resolve => {
      let accessedRoutes
      if (roles.includes('admin')) {
		 
        accessedRoutes = asyncRoutes || []
      } else {
		  
        accessedRoutes = filterAsyncRoutes(asyncRoutes, roles)
      }
	  console.log(accessedRoutes)
	  // 便利数组
	  // 以上代码是自带的
	  // 以下是有用代码
	  function List(accessedRoutes,Urlkey){
	    console.log(Urlkey,'便利数组中的Urlkey')
	    var data = new Array
	    var dataCchildren = new Array
	    for(var i=0;i<accessedRoutes.length;i++){
	    // for(var i=0;i<accessedRoutes.length-1;i++){
			 console.log('1')
	      for(var l=0;l<Urlkey.length;l++){
	        if(accessedRoutes[i].meta.Kid == Urlkey[l]){
	          data.push(accessedRoutes[i])
	        }else{
	        }
	      }
	    }
	    for(var k=0;k<data.length;k++){
			console.log('2')
	      for(var a=0;a<data[k].children.length;a++){
	        for(var b=0;b<Urlkey.length;b++){
	          if(data[k].children[a].meta.Kid == Urlkey[b]){
	            console.log(data[k].children[a])
	            dataCchildren.push(data[k].children[a]) 
	          }
	        }
	      }
	    }
	    console.log(data)
	    console.log(dataCchildren)
	    for(var c=0;c<data.length;c++){
	      if(data[c].children.length>1){
	        data[c].children = []
	        for(var e=0;e<dataCchildren.length;e++){
	          if(dataCchildren[e].meta.Fid == data[c].meta.Kid){
	            console.log(dataCchildren[c])
	            data[c].children.push(dataCchildren[e])
	          }
	        }
	      } 
	    }
	    return data
	  }
			 if (localStorage.getItem('usertype') == 1) {
				 
				 // var Urlkey = [1,2,11,13,15,17,64,101,102,103,104]
				 var Urlkey = [77,1]
				 var data=List(accessedRoutes,Urlkey)
				 commit('SET_ROUTES', data)
				 resolve(data)
				 return
			 }
			 else{
				 console.log('2')
				 var Urlkey = []
				 var data=List(accessedRoutes,Urlkey)
				 console.log(data)
				 commit('SET_ROUTES', data)
				 resolve(data)
				 return
				  
			 }
			 // 结束
      // commit('SET_ROUTES', accessedRoutes)
      // resolve(accessedRoutes)
    })
  }
}

export default {
  namespaced: true,
  state,
  mutations,
  actions
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值