1. Idea
Each user has his own role, and different roles have different asynchronous routes (each role has constant routes). At this time, it is necessary to calculate the routing information in all user information returned by the backend after the user successfully logs in. The routes owned by the user are filtered out in asynchronous routing, and then dynamically added to the router. Finally, with the recursive creation of the route navigation menu, the routes corresponding to the user’s role are displayed to the user.
Related codes in 2.router
//Implement template routing configuration through vue-router plug-in import { createRouter, createWebHashHistory } from 'vue-router' import { constantRoute } from './routes' //Create router const router = createRouter({ //routing mode hash history: createWebHashHistory(), routes: constantRoute, //Scroll behavior scrollBehavior() { return { left: 0, top: 0, } }, }) export default router
//Exposed configuration route (constant route): a route that all users can access export const constantRoute = [ { //Log in path: '/login', component: () => import('@/views/login/index.vue'), name: 'login', meta: { title: 'Login', //Menu title hidden: true, //Represents whether the routing title is hidden in the menu true: hidden false: not hidden icon: 'Promotion', //The icon to the left of the menu text, supports all element-plus icons }, }, { //Route to display data after successful login path: '/', component: () => import('@/layout/index.vue'), name: 'layout', meta: { title: '', hidden: false, icon: '', }, redirect: '/home', children: [ { path: '/home', component: () => import('@/views/home/index.vue'), meta: { title: 'Home', hidden: false, icon: 'HomeFilled', }, }, ], }, { //404 path: '/404', component: () => import('@/views/404/index.vue'), name: '404', meta: { title: '404', hidden: true, icon: 'DocumentDelete', }, }, { path: '/screen', component: () => import('@/views/screen/index.vue'), name: 'Screen', meta: { hidden: false, title: 'Data Big Screen', icon: 'Platform', }, }, ] //Asynchronous routing export const asnycRoute = [ { path: '/acl', component: () => import('@/layout/index.vue'), name: 'Acl', meta: { title: 'Permission Management', icon: 'Lock', }, redirect: '/acl/user', children: [ { path: '/acl/user', component: () => import('@/views/acl/user/index.vue'), name: 'User', meta: { title: 'User Management', icon: 'User', }, }, { path: '/acl/role', component: () => import('@/views/acl/role/index.vue'), name: 'Role', meta: { title: 'Role Management', icon: 'UserFilled', }, }, { path: '/acl/permission', component: () => import('@/views/acl/permission/index.vue'), name: 'Permission', meta: { title: 'Menu Management', icon: 'Monitor', }, }, ], }, { path: '/product', component: () => import('@/layout/index.vue'), name: 'Product', meta: { title: 'Product Management', icon: 'Goods', }, redirect: '/product/trademark', children: [ { path: '/product/trademark', component: () => import('@/views/product/trademark/index.vue'), name: 'Trademark', meta: { title: 'Brand Management', icon: 'ShoppingCartFull', }, }, { path: '/product/attr', component: () => import('@/views/product/attr/index.vue'), name: 'Attr', meta: { title: 'Attribute Management', icon: 'ChromeFilled', }, }, { path: '/product/spu', component: () => import('@/views/product/spu/index.vue'), name: 'Spu', meta: { title: 'SPU Management', icon: 'Calendar', }, }, { path: '/product/sku', component: () => import('@/views/product/sku/index.vue'), name: 'Sku', meta: { title: 'SKU Management', icon: 'Orange', }, }, ], }, ]
3.Related codes in store
//Introduce all routes import { constantRoute, asnycRoute} from '@/router/routes' //Introduce deep copy method //@ts-expect-error import cloneDeep from 'lodash/cloneDeep' import router from '@/router' //Used to filter the asynchronous routes that the current user needs to display function filterAsyncRoute(asnycRoute: any, routes: any) { return asnycRoute.filter((item: any) => { if (routes.includes(item.name)) { if (item.children & amp; & amp; item.children.length > 0) { //Silicon Valley 333 account: product\trademark\attr\sku item.children = filterAsyncRoute(item.children, routes) } return true } }) }
//Calculate the asynchronous routes that the current user needs to display const userAsyncRoute = filterAsyncRoute( cloneDeep(asnycRoute), result.data.routes, ) //The data required for the menu has been sorted out this.menuRoutes = [...constantRoute, ...userAsyncRoute]; //Currently, the router manages only constant routes: asynchronous routes are dynamically added after the user has calculated them. [...userAsyncRoute].forEach((route: any) => { router.addRoute(route) })
4. Layout the menu component in the container component
<template> <template v-for="(item, index) in menuList" :key="item.path"> <!--No sub-routes--> <template v-if="!item.children"> <el-menu-item :index="item.path" v-if="!item.meta.hidden" @click="goRoute"> <el-icon> <component :is="item.meta.icon"></component> </el-icon> <template #title> <span>{<!-- -->{ item.meta.title }}</span> </template> </el-menu-item> </template> <!-- There are sub-routes but there is only one sub-route --> <template v-if="item.children & amp; & amp; item.children.length == 1"> <el-menu-item :index="item.children[0].path" v-if="!item.children[0].meta.hidden" @click="goRoute"> <el-icon> <component :is="item.children[0].meta.icon"></component> </el-icon> <template #title> <span>{<!-- -->{ item.children[0].meta.title }}</span> </template> </el-menu-item> </template> <!-- There are sub-routes and the number is greater than one 1 --> <el-sub-menu :index="item.path" v-if="item.children & amp; & amp; item.children.length > 1"> <template #title> <el-icon> <component :is="item.meta.icon"></component> </el-icon> <span>{<!-- -->{ item.meta.title }}</span> </template> <Menu :menuList="item.children"></Menu> </el-sub-menu> </template> </template> <script setup lang="ts"> import { useRouter } from 'vue-router'; //Get all routing arrays passed by the parent component defineProps(['menuList']); //Get router object let $router = useRouter(); //Callback for click menu const goRoute = (vc: any) => { //route jump $router.push(vc.index); } </script> <style scoped></style>
The knowledge points of the article match the official knowledge files, and you can further learn relevant knowledge. Vue entry skill tree Home page Overview 39844 people are learning the system