源码 https://github.com/ohoherror/...
menuItem.js
外围:判断菜单还有没有children,有children就递归,没有就展现菜单名
<template> <template v-for="item in arrList"> <el-menu-item v-if='!item.children' @click="toMenu(item)" :key="'/' + item.url" :index="'/' + item.url"> <span>{{ item.name }}</span> </el-menu-item> <el-sub-menu :index="item.menuId.toString()" v-else> <template #title><span>{{ item.name }}</span></template> <menu-item :arrList="item.children" @toMenu="toMenu"></menu-item> </el-sub-menu> </template></template><script setup>import { pathArr } from '@/router/routes'import menuItem from './menuItem.vue'import { useRouter } from 'vue-router'import { useStore } from 'vuex';//vue3 props的获取const props = defineProps({ arrList: Array,});const router = useRouter()let store = useStore()const toMenu = (ele) => { let checkedList = store.state.tabList console.log(checkedList) if (pathArr().includes('/' + ele.url)) { let ids = checkedList.map(ele => ele.menuId) //判断tabs是否存在该菜单 if (!ids.includes(ele.menuId)) { checkedList.push(ele) } store.commit('setTabList', checkedList) router.push({ path: '/' + ele.url }) } else { ElMessage.error('暂无组件') }}</script>
leftNav.js 左侧菜单总列表
<template> <el-row class=""> <el-col> <el-menu :collapse="isCollapse" class="el-menu-vertical-demo" :default-active="curPath" @open="handleOpen" @close="handleClose"> <el-sub-menu v-for="item in menuList" :key="item.menuId" :index="item.menuId.toString()"> <template #title> <span>{{ item.name }}</span> </template> <!-- 此处调用menu-item组件 --> <menu-item :arrList="item.children"></menu-item> </el-sub-menu> </el-menu> </el-col> </el-row></template><script setup>import { reactive, ref, onMounted, watch } from 'vue'import navApi from '@/api/navApi'import { useRouter } from 'vue-router'import { useStore } from 'vuex';import { toRaw } from '@vue/reactivity'import { listMenu } from '../../../config/menu'import menuItem from './menuItem.vue'const router = useRouter()const menuList = ref([])let curPath = ref()const isCollapse = ref(false)onMounted(() => { if (router.name !== 'login') { getNav() }})//路由监听watch(() => router.currentRoute.value.path, (newValue, oldValue) => { curPath.value = newValue}, { immediate: true })const handleOpen = () => {}const handleClose = () => {}const getNav = () => { menuList.value = listMenu}</script>
菜单列表测试数据menu.js
export const listMenu = [{ menuId: 1, name: "系统管理", open: null, orderNum: 0, parentId: 0, parentName: null, perms: null, type: 0, url: null, children: [ { icon: "role", children: [ { icon: "role", children: [ { icon: "role", children: null, menuId: 144, name: "测试治理", open: null, orderNum: 2, parentId: 44, parentName: null, perms: null, type: 1, url: "sys/test", } ], menuId: 44, name: "子系统治理", open: null, orderNum: 2, parentId: 3, parentName: null, perms: null, type: 1, } ], menuId: 3, name: "角色治理", open: null, orderNum: 2, parentId: 1, parentName: null, perms: null, type: 1, }, { icon: "menu", children: null, menuId: 4, name: "菜单治理", open: null, orderNum: 3, parentId: 1, parentName: null, perms: null, type: 1, url: "sys/menu", } ]}]