使用VueRouter自动生成导航菜单

我们在搭建Web的后台管理系统时,会选择 ElementUI 进行快速搭建,但是在某些场景下,单纯的使用组件是不能满足要求的。

因为需求是在不断增加,不断变化的,如果像 ElementUI 给的示例去维护后台管理系统的菜单栏的话,代码会非常臃肿,维护起来也不是很方便:

在这里插入图片描述
菜单是一个树形结构,VueRouter的配置项 routes 也是树形结构,每一个具体的路由都对应着一个页面,因此可以利用 routes 来配合 ElementUI菜单组件 动态生成菜单。

大体思路如下:

(1)拿到routes: this.router.options.routes

const routes = [
    {
        path: '/',
        component: () => import('../views/Home'),
        meta: {title: "组卷管理"},
        children: [
            {
                path: 'hand',
                component: () => import('../views/Home'),
                meta: {title: "手动组卷"}
            },
            {
                path: 'mid',
                component: () => import('../views/Home'),
                meta: {title: "自动组卷"}
            },
        ]
    },
    {
        path: '/exam',
        component: () => import('../views/Home'),
        meta: {title: "考试管理"},
        children: [
            {
                path: 'mid',
                component: () => import('../views/Home'),
                meta: {title: "期中考试"}
            },
            {
                path: 'final',
                component: () => import('../views/Home'),
                meta: {title: "期末考试"}
            },
            {
                path: 'else',
                component: () => import('../views/Home'),
                meta: {title: "其他考试"},
                children: [
                    {
                        path: 'unit',
                        component: () => import('../views/Home'),
                        meta: {title: "单元测验"}
                    },
                    {
                        path: 'daily',
                        component: () => import('../views/Home'),
                        meta: {title: "日常作业"}
                    },
                ]
            },
        ]
    }
]

为了方便后续理解,我简化下结构就是

let routes = [
	{ path, meta, children:[{path,meta}, {path,meta}, ...] },
	{ path, meta, chidren: [ {path, meta, children: [...]} ] }
]

我们需要 path 作为 router-link 的目标值,

需要 meta 中的 自定义title 作为菜单项显示的文字,

需要 children.length 判断该节点是否为叶子结点,

需要 children 进行深搜

(2)创建菜单项组件 MyMenu(根节点)、SubMenu(非叶子节点)、MenuItem(叶子节点)

MyMenu 对应一个根节点,是无需有内容的,可以搭配 ElementUI 的 < el-menu > 使用

<template>
    <div class="menu">
        <el-menu>
			// todo
        </el-menu>
    </div>
</template>

接着我们可以自顶下下进行思考,用我们现在有的条件去看看 我们需要什么样的 SubMenu 和 MenuItem

先看简单 的 MenuItem, 对应叶子节点

<template>
    <div>
        <el-menu-item :index="idx">
            <router-link tag="div" :to="resolvePath(cur.path)" >{{cur.meta.title}}-{{resolvePath(cur.path)}}</router-link>
        </el-menu-item>
    </div>
</template>

接着是 非叶子节点 SubMenu

<template>
    <div>
       <el-submenu :index="idx">
           <template slot="title">
               <i class="el-icon-location"></i>
               <span>{{cur.meta.title}}-{{resolvePath(cur.path)}}</span>
           </template>
           <div>
               <template v-for="(item, num) of cur.children">
                   <sub-menu v-if="item.children && item.children.length>0" :cur="item" :pre_url="resolvePath(cur.path)" :key="item.path" :idx="getIdx(num)"></sub-menu>
                   <menu-item v-else :cur="item" :pre_url="resolvePath(cur.path)" :key="item.path" :idx="getIdx(num)"></menu-item>
               </template>
           </div>
       </el-submenu>
    </div>
</template>

剩下的还有 index问题收缩问题,还有父子同步激活的问题,以及如何使用 DOM 实现不用Vue,后续说明

最后的效果是这个样的

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值