vue3后台管理系统实现动态侧边导航菜单管理(ElementPlus组件)

在这里插入图片描述

记住 一级(el-sub-menu)的都是只是展示的 点击跳转的都是一级下的子级(el-menu-item)
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

完整展示
在这里插入图片描述

1:在登陆功能进行登陆 获取menu列表
注册路由表的时候 把文件进行创建好 因为注册的方法需要获取这个路径
整个router下的main product等等都要创建

在这里插入图片描述
在这里插入图片描述

//1:发送你的用户名和密码获取token和用户信息**
//2:拿着token获取菜单列表接口 (我的项目封装的axios  ,这里演示的话就写这么个意思 知道就行)**
 const userMenuData=await axios.get('xxxx'{'token':'xxxxx'}) 
 //3:保存在 vuex中
 //4:把菜单权限注入到路由表内
 
 const  mapMenusToRouters=(userMenus: any[])=> {
    console.log(userMenus, 'userMenus')
    // type==1说明有二级 type==2 就是二级
    // 保存处理好的路由。
    const routes: RouteRecordRaw[] = [];
    // 获取所有的路由文件
    const allRoutes: RouteRecordRaw[] = [];
    // 1先查询路由目录文件 获取main下的ts文件 
    const routeFiles = require.context('../router/main', true, /\.ts/)
    // 2  获取keys()  引入文件
    routeFiles.keys().forEach(key => {
        // 3切割文件./  .ts  
        const route = require('../router/main' + key.split('.')[1])
        // 4  把文件追加到数组 allRoutes中
        allRoutes.push(route.default)
    });
    const _recurseGetRoute = (menus: any[]) => {
        for (const menu of menus) {
            if (menu.type == 1) {
                _recurseGetRoute(menu.children ?? [])
            } else {
                // type==2  没有了子集
                const route = allRoutes.find((route) => {
                    return route.path == menu.url
                })
                if (route) {
                    routes.push(route)
                } 
            }
        }
    }  
    _recurseGetRoute(userMenus)
    if (routes) {
        return routes

    } else {
        return []

    }

}
 //记得 import {useStore}  from 'store';
   const store = useStore(); 
  const userMenu = computed(() => {
    return store.state.login.userMenus;
 });  
 //调用函数进行处理
const routes = mapMenusToRouters(userMenus)
  //放在router.ts的main 下的children中=========>路由表注册完毕
routes.forEach((key: RouteRecordRaw) => router.addRoute('main', key)  )

2:侧边菜单界面

<template>
  <div class="nav-menu">
    <div class="logo">
      <img class="img" src="~@/assets/img/logo.svg" alt="logo" />
      <span class="title" >vue3+ts</span>
    </div>
     
    <el-menu
      :default-active="dafaultValue"
      background-color="#0c2135"
      text-color="#b7bdc3"
      :collapse="isCollapse"
      active-text-color="#0a60bd"
      class="el-menu-vertical"
    >
      <template v-for="item in userMenu" :key="item.id">
      
        <template v-if="item.type == 1">
          <el-sub-menu :index="item.id + ''">
            <template #title>
              <el-icon><Platform /></el-icon>
              <span>{{ item.name }}</span>
            </template>
            <template v-for="subItem in item.children" :key="subItem.id">
              <el-menu-item
                :index="subItem.id + ''"
                @click="handleMenuItemClick(subItem)"
              >
                <template #title>
                  <el-icon><Platform /></el-icon>
                  <span>{{ subItem.name }}</span>
                </template>
              </el-menu-item>
            </template>
          </el-sub-menu>
        </template>
        <template v-else-if="item.type === 2">
          <el-menu-item :index="item.id + ''">
            <span>{{ item.name }}</span>
          </el-menu-item>
        </template>
      </template>
    </el-menu>
  </div>
</template>
<script setup lang="ts">
import { useRouter, useRoute } from "vue-router";
 import { useStore } from "@/store/index";
 
//1:vuex获取菜单列表   
  const store = useStore(); 
  const userMenu = computed(() => {
    return store.state.login.userMenus;
 }); 
 //2:点击el-menu-item上的按钮跳转的函数
 const router = useRouter();
 const handleMenuItemClick = (item: any) => {
 // item.url不存在就跳转到自己定义的界面 比如404 (/not-found)
  router.push({ path: item.url ?? "/not-found" });
};
//3:  el-sub-menu上有一个属性是dafaultValue
//  意思是默认选择的路由菜单 不能写死 不然我刷新的时候 就不能显示当前的选中菜单,而是选中写死的菜单
//  比如 我写死的dafaultValue是用户管理,当前点击菜单管理进行刷新数据的时候 他会跑到用户管理里面 这是错误的

const pathMapToMenus = (userMenu: any[], currentPath: string): any => {
    for (const menu of userMenu) {
        // 如果type==1  那么就是含有二级
        if (menu.type == 1) {
            console.log(menu)
            // 调用函数本身 把结果返回给我
            const findMenu = pathMapToMenu(menu.children ?? [], currentPath)
            if (findMenu) {
                return findMenu
            }
            // 如果type==2    那么直接判断后把结果返回给我
        } else if (menu.type == 2 && currentPath == menu.url) {
            console.log(menu, '2')
            return menu
        }
    }
}
  const route = useRoute();
  const currentPath = route.path;
  const menu = pathMapToMenu(userMenu.value, currentPath);
  const dafaultValue = ref(menu.id + "");
</script>

以上把侧边菜单展示实现了,, 但是实现跳转的话 路由表必须有相对应的路由

router/index.ts

import { createRouter, createWebHashHistory, RouteRecordRaw } from 'vue-router'
import { accountLoginRequest, RequestUserInfoByid, RequestUserMenusByRoleId } from '@/service/login/login'; 
const routes: Array<RouteRecordRaw> = [
  {
    path: '/',
    redirect: '/main'
  },
  {
    path: '/login',
    name: 'login', 
    component: () => import(/* webpackChunkName: "about" */ '../views/login/login.vue')
  },
  {
    path: '/main',
    name: 'main', 
    redirect:'/main/system/user',
    component: () => import(/* webpackChunkName: "about" */ '../views/main/main.vue'),
    children:[]
  },
   {
   //404请求不存在的路径
    path: '/:pathMatch(.*)*',
    component: () => import('@/views/not-found/not-found.vue')
  }
]

const router = createRouter({
  history: createWebHashHistory(),
  routes
})
// 导航守卫
router.beforeEach((to) => {
  if (to.path !== '/login') {
    const token = window.localStorage.getItem('token')
    if (!token) {
      return '/login'
    }  
  } 
})
console.log(router, 'router')
export default router

  • 1
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
实现动态路由和动态侧边菜单栏,需要先使用Vue Router来处理路由,然后使用Vue3的组合式API来实现动态路由和动态侧边菜单栏。 首先,在Vue Router中定义路由时,可以使用动态路由参数来实现动态路由。例如: ```javascript const routes = [ { path: '/user/:id', component: User } ] ``` 在这个例子中,路由为/user/:id,其中:id是动态的,可以根据需要传入不同的参数来生成不同的路由。 然后,在组件中使用Vue3的组合式API来获取当前路由参数,例如: ```javascript import { useRoute } from 'vue-router' export default { setup() { const route = useRoute() console.log(route.params.id) // 输出当前路由参数 } } ``` 接下来,可以根据当前路由参数来生成动态侧边菜单栏。例如: ```javascript import { useRoute, useRouter } from 'vue-router' export default { setup() { const router = useRouter() const route = useRoute() const menuItems = [ { name: '用户列表', path: '/users' }, { name: '用户详情', path: `/user/${route.params.id}` }, { name: '添加用户', path: '/add-user' }, ] return { menuItems, goToPage(path) { router.push(path) } } } } ``` 在这个例子中,使用useRouter来获取路由实例,然后根据当前路由参数生成动态侧边菜单栏。同时,定义一个goToPage方法,用来跳转到指定的页面。 最后,在侧边菜单组件中使用v-for指令来渲染菜单项,例如: ```html <template> <div> <ul> <li v-for="item in menuItems" :key="item.path" @click="goToPage(item.path)"> {{ item.name }} </li> </ul> </div> </template> ``` 通过这样的方式,就可以实现动态路由和动态侧边菜单栏了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值