找回密码
 立即注册
首页 业界区 业界 (系列十)Vue3中菜单和路由的结合使用,实现菜单的动态 ...

(系列十)Vue3中菜单和路由的结合使用,实现菜单的动态切换(附源码)

路逸思 3 天前
说明

    该文章是属于OverallAuth2.0系列文章,每周更新一篇该系列文章(从0到1完成系统开发)。
    该系统文章,我会尽量说的非常详细,做到不管新手、老手都能看懂。
    说明:OverallAuth2.0 是一个简单、易懂、功能强大的权限+可视化流程管理系统。
友情提醒:本篇文章是属于系列文章,看该文章前,建议先看之前文章,可以更好理解项目结构。
qq群:801913255
有兴趣的朋友,请关注我吧(*^▽^*)。
1.bmp

关注我,学不会你来打我
上篇回顾
在上一篇:(系列九)使用Vue3+Element Plus创建前端框架(附源码) 博客中,我们说道,使用vue3+element plus 创建项目,成功实现了布局组件container+菜单组件Menu搭建框架。
布局样式如下:
2.png

然而我们只是实现了界面的搭建,并没有实现任何交互。
也因此有很多人在询问,如何做动态切换菜单。
我想说,不要慌,一切需求都会安排到位。
接下来我们就要实现菜单和路由的结合使用,做到动态切换菜单。
安装路由
命令:npm install vue-router
安装成功后,手动创建以下目录及文件
3.png

base-routes.ts 内容
  1. import { createRouter, createWebHashHistory, RouteRecordRaw } from 'vue-router';
  2. import Panel from '../../views/panel/index.vue';
  3. export const routes: RouteRecordRaw[] = [];
  4. routes.push(
  5.   {
  6.     path: '/panel',
  7.     component: Panel,
  8.     name: "面板",
  9.   },
  10.   {
  11.     path: '/menu',
  12.     redirect: '/menu/index',
  13.     meta: { title: '菜单管理' },
  14.     name: "菜单管理",
  15.     children: [
  16.       {
  17.         path: '/menu',
  18.         name: '菜单',
  19.         component: () => import('../../views/menu/index.vue'),
  20.         meta: { title: '菜单', requireAuth: true, affix: true, closable: false },
  21.       }
  22.     ]
  23.   },
  24.   {
  25.     path: '/user',
  26.     meta: { title: '用户管理' },
  27.     name: "用户管理",
  28.     children: [
  29.       {
  30.         path: '/user',
  31.         name: '用户',
  32.         component: () => import('../../views/user/index.vue'),
  33.         meta: { title: '用户' },
  34.       }]
  35.   },
  36. )
  37. //创建路由,并且暴露出去
  38. const router = createRouter({
  39.   history: createWebHashHistory(), //开发环境
  40.   //history:createWebHistory(), //正式环境
  41.   routes
  42. })
  43. export default router
复制代码
该文件主要是配置菜单的json文件,及暴露路由。里面的属性应该不必多说,很容易看懂。
至于views文件夹中的vue文件内容,大家随便填写什么都可以,只要三个页面的内容不一样即可。
然后在main.ts中配置路由,全局变量。
如下图:
4.png

使用路由
做完以上步骤,接下来的工作就很简单了,我们只需要,在HelloWorld.vue(接上一篇文章代码),中修改代码如下
el-main中的内容替换为 el-menu中添加 router属性然后导入base-routes.ts 文件,并添加如下代码
  1.   const menu = routes;
  2.     return {
  3.       menu,
  4.     };
复制代码
完整的HelloWorld.vue代码如下
  1. <template>
  2.   
  3.     <el-container style="height: 100%; overflow: hidden">
  4.       <el-aside width="auto">
  5.         <el-menu
  6.           class="el-menu-vertical-demo"
  7.           background-color="#545c64"
  8.           text-color="#fff"
  9.           active-text-color="#ffd04b"
  10.           style="height: 100%"
  11.           router
  12.         >
  13.          
  14.             
  15.             
  16.               OverallAuth2.0
  17.             
  18.          
  19.          
  20.             <el-sub-menu
  21.               v-if="menuItem.children && menuItem.children.length"
  22.               :index="menuItem.path"
  23.               :key="menuItem.name"
  24.             >
  25.               <template #title>
  26.                 <el-icon><location /></el-icon>{{ menuItem.name }}</template
  27.               >
  28.               <el-menu-item
  29.                 v-for="subMenuItem in menuItem.children"
  30.                 :index="subMenuItem.path"
  31.                 :route="{ name: subMenuItem.name }"
  32.                 :key="subMenuItem.name"
  33.                 style="cursor: pointer"
  34.               >
  35.                 {{ subMenuItem.name }}
  36.               </el-menu-item>
  37.             </el-sub-menu>
  38.             <el-menu-item
  39.               v-else
  40.               :index="menuItem.path"
  41.               :key="menuItem.path"
  42.               :route="{ name: menuItem.name }"
  43.               style="cursor: pointer"
  44.             >
  45.               {{ menuItem.name }}
  46.             </el-menu-item>
  47.          
  48.         </el-menu>
  49.       </el-aside>
  50.       <el-container>
  51.         <el-header class="headerCss">
  52.          
  53.             
  54.               
  55.               
  56.                 OverallAuth2.0 权限管理系统
  57.               
  58.             
  59.             
  60.               
  61.               
  62.                 微信公众号:不只是码农
  63.               
  64.             
  65.          
  66.         </el-header>
  67.         <el-main>
  68.           <router-view></router-view>
  69.         </el-main>
  70.       </el-container>
  71.     </el-container>
  72.   
  73. </template>
复制代码
做好这些后,我们就能够动态切换菜单。
效果如下图
5.gif

是不是很完美。
不,我想说,还没有完,还差的远。
接着看往下看
加入tab标签
可能大家也发现了,在我们点击左侧菜单时,访问过的菜单,在系统中没有历史访问标签。
现在我们做以下操作,把访问过的菜单记录到tab标签中,以防止系统重新对接口进行请求。
同样修改HelloWorld.vue文件。
把el-main标签中的内容换成
  1. <el-tabs
  2.             v-if="tabsList.length > 0"
  3.             v-model="defaultActive"
  4.             class="demo-tabs"
  5.             @click="tabsClick(defaultActive)"
  6.             @tab-remove="tabRemoveClick"
  7.           >
  8.             <el-tab-pane
  9.               v-for="item in tabsList"
  10.               :label="item.name"
  11.               :name="item.path"
  12.               :key="item.path"
  13.               :closable="item.path == '/panel' ? false : true"
  14.               style="font-size: 16px;"
  15.             >
  16.               <router-view></router-view>
  17.             </el-tab-pane>
  18.           </el-tabs>
复制代码
在el-menu-item标签中,加入菜单切换事件menuItemClick()setup()方法中的内容替换成
  1. setup() {
  2.     const defaultActive = ref("/panel");
  3.     const menu = routes;
  4.     const tabsList = ref<RouteRecordRaw[]>([]);
  5.       onMounted(() => {
  6.       tabsList.value.push(routes[0]);
  7.       router.push(routes[0]);
  8.     });
  9.     //菜单项点击事件
  10.     function menuItemClick(subMenuItem: RouteRecordRaw) {
  11.       // tabList中不存在则追加
  12.       if (!tabsList.value.some((sub) => sub.path == subMenuItem.path)) {
  13.         tabsList.value.push(subMenuItem);
  14.       }
  15.       defaultActive.value = subMenuItem.path;
  16.     }
  17.     //菜单标签点击事件
  18.     const tabsClick = (item: string) => {
  19.       defaultActive.value = item;
  20.       router.push({ path: item });
  21.     };
  22.     //菜单标签移除事件
  23.     const tabRemoveClick = (path: any) => {
  24.       tabsList.value.map((item: { path: string }, index: any) => {
  25.         if (item.path == path) tabsList.value.splice(index, 1); //index 当前元素索引;1:需要删除的元素个数
  26.       });
  27.       defaultActive.value = "/panel";
  28.       router.push({ path: "/panel" });
  29.     };
  30.     return {
  31.       menu,
  32.       tabsList,
  33.       defaultActive,
  34.       tabsClick,
  35.       tabRemoveClick,
  36.       menuItemClick,
  37.     };
  38.   },
复制代码
以上是HelloWorld.vue文件中变动的代码。
我们来看下完整的HelloWorld.vue文件代码
  1. <template>
  2.   
  3.     <el-container style="height: 100%; overflow: hidden">
  4.       <el-aside width="auto">
  5.         <el-menu
  6.           class="el-menu-vertical-demo"
  7.           background-color="#545c64"
  8.           text-color="#fff"
  9.           active-text-color="#ffd04b"
  10.           style="height: 100%"
  11.           router
  12.         >
  13.          
  14.             
  15.             
  16.               OverallAuth2.0
  17.             
  18.          
  19.          
  20.             <el-sub-menu
  21.               v-if="menuItem.children && menuItem.children.length"
  22.               :index="menuItem.path"
  23.               :key="menuItem.name"
  24.             >
  25.               <template #title>
  26.                 <el-icon><location /></el-icon>{{ menuItem.name }}</template
  27.               >
  28.               <el-menu-item
  29.                 v-for="subMenuItem in menuItem.children"
  30.                 :index="subMenuItem.path"
  31.                 :route="{ name: subMenuItem.name }"
  32.                 :key="subMenuItem.name"
  33.                 style="cursor: pointer"
  34.               >
  35.                 {{ subMenuItem.name }}
  36.               </el-menu-item>
  37.             </el-sub-menu>
  38.             <el-menu-item
  39.               v-else
  40.               :index="menuItem.path"
  41.               :key="menuItem.path"
  42.               :route="{ name: menuItem.name }"
  43.               style="cursor: pointer"
  44.             >
  45.               {{ menuItem.name }}
  46.             </el-menu-item>
  47.          
  48.         </el-menu>
  49.       </el-aside>
  50.       <el-container>
  51.         <el-header class="headerCss">
  52.          
  53.             
  54.               
  55.               
  56.                 OverallAuth2.0 权限管理系统
  57.               
  58.             
  59.             
  60.               
  61.               
  62.                 微信公众号:不只是码农
  63.               
  64.             
  65.          
  66.         </el-header>
  67.         <el-main>
  68.           <router-view></router-view>
  69.         </el-main>
  70.       </el-container>
  71.     </el-container>
  72.   
  73. </template>                                                
复制代码
我们看下效果
6.gif

后端WebApi 预览地址:http://139.155.137.144:8880/swagger/index.html
前端vue 预览地址:http://139.155.137.144:8881
关注公众号:发送【权限】,获取前后端代码
有兴趣的朋友,请关注我微信公众号吧(*^▽^*)。
7.bmp

关注我:一个全栈多端的宝藏博主,定时分享技术文章,不定时分享开源项目。关注我,带你认识不一样的程序世界

来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
您需要登录后才可以回帖 登录 | 立即注册