乐趣区

关于vue3:vue3-elmenu-elementplus多级菜单递归写法

源码 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",
        }
    ]
}]
退出移动版