源码 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",
}
]
}]