引言

作为web前端开发,几乎所有的web系统界面都会使用到菜单栏,而大多数的左侧菜单栏都是可收缩的。接下来就一起学习下如何根据从后端获取到的数据,动态的加载菜单栏。

GitHub链接

链接: 菜单栏demo.

Element-UI

我们可以使用element官网的官方demo作为基础,因为官网上的demo并不是动态获取的数据,而是写死的菜单项,且不能做到可收缩。下面将具体介绍如何实现动态加载菜单项以及可收缩菜单的实现。

数据格式

数据格式不唯一,内部属性有些是可以不需要的,但是id,parentId,name,actionUrl在这里是必需的。当然主要还是看个人的需求。

// An highlighted block
var _list = [
        {
            id: '6',
            name: '个人算法',
            parentId: '0',
            hasChildren: true,
            parentName: null,
            url: '',
            actionUrl: '',
            visible: '1',
            check: false,
            children: [
                {
                    id: '1',
                    name: '用户管理',
                    parentId: '6',
                    hasChildren: false,
                    parentName: "个人算法",
                    text: "用户管理",
                    url: "/alm/user/list",
                    actionUrl: '/user/list',
                    children: []
                },
                {
                    id: '2',
                    name: '策略设置',
                    parentId: '6',
                    hasChildren: false,
                    parentName: "个人算法",
                    text: "策略设置",
                    url: "/alm/strategy/list",
                    actionUrl: '/strategy/list',
                    children: []
                }
          ]
        },
        {
            id: '8',
            name: '个人方案',
            parentId: '0',
            hasChildren: true,
            parentName: null,
            url: '',
            actionUrl: '',
            visible: '1',
            check: false,
            children: [
                {
                    id: '3',
                    name: '方案管理',
                    parentId: '8',
                    hasChildren: false,
                    parentName: "个人方案",
                    text: "方案管理",
                    url: "/alm/programme/list",
                    actionUrl: '/programme/list',
                    children: []
                },
                {
                    id: '4',
                    name: '数据统计',
                    parentId: '8',
                    hasChildren: false,
                    parentName: "个人方案",
                    text: "数据统计",
                    url: "/alm/datas/list",
                    actionUrl: '/datas/list',
                    children: []
                }
            ]
        }
    ]

传参到菜单栏组件中

用上述的_list赋值给menus,传参到菜单栏组件中。数据同样可以从后台获取到,直接赋值给你要传的参数即可。菜单栏组件内接受到后,即可使用该数据。

	<!--侧边栏-->
    <left-menu :top-title="title" :menus="menus" ></left-menu>

el-menu的主要写法

在实现过程中,该demo只测试过一级到二级的菜单,尚未测试过三级以上的。如果有以上的需求,只要理清实现的原理,相信也是可以撸出来的。
如果对el-menu中的el-submenu以及el-menu-item有不太理解的地方,可以先去看看官网的基础demo。
链接:element官网menu

<el-menu
                class="el-menu-vertical-demo"
                :unique-opened="true"
                :router="true"
                @open="handleOpen"
                @close="handleClose"
                background-color="#324157"
                text-color="#fff"
                active-text-color="#2bb8ed"
                :default-active="defaultActive"
                :collapse="this.$store.state.isCollapse">
            <el-menu-item index="8">
                <i class="el-icon-phone-outline"></i>
                <span>{{topTitle}}</span>
            </el-menu-item>
            <template v-for="item in menus" :index="item.id">
                <template v-if="item.hasChildren" >
                    <el-submenu  :index="item.id">
                        <template slot="title" >
                            <i class="el-icon-menu"></i>
                            <span class="title-instance-left">{{item.name}}</span>
                        </template>
                        <el-menu-item v-for="subItem in item.children" :key="subItem.id" :index="subItem.actionUrl" @click="openUrl(subItem.actionUrl)">
                            <span class="title-instance-left">{{ subItem.name }}</span>
                        </el-menu-item>
                    </el-submenu>
                </template>
                <template v-else>
                    <el-menu-item :index="item.actionUrl" @click="openUrl(item.actionUrl)">
                        <label>{{ item.name }}</label>
                    </el-menu-item>
                </template>
            </template>
        </el-menu>

如何实现可收缩

通常我们是通过点击按钮来触发事件,达到收缩菜单栏的效果。这里的问题主要集中于,左侧菜单栏的展开与收缩,以及右侧实际内容区域的跟随变化。即,当左侧收缩时,右侧内容区域会向左跟进;左侧展开时,右侧内容区域会向右搜索。

而demo中针对这一问题,主要是运用transition这个属性来实现的。所以,就需要使用到变量来动态的切换class类,达到不同的样式效果。

引用右侧内容组件中的动态class

根据变量isLeftOpen来进行控制右侧内容区域的收缩的。

	<!--右侧路由部分-->
    <div :class="['inner-layout__right-part', {'inner-layout__right-part_open': !isLeftOpen},{'inner-layout__right-part_close': isLeftOpen}]">
         <router-view ></router-view>
    </div>
el-menu的收缩

el-menu的收缩主要是根据el-menu中的collapse属性来控制的

//动态绑定collapse,isCollapse是写在全局中的
:collapse="this.$store.state.isCollapse"
通过点击按钮实现更改变量值,达到可收缩效果

点击收缩按钮,触发事件,更改对应的变量,实现可收缩效果。

	transformMenu(){
         if(this.$store.state.isCollapse === true){
            	this.$store.commit('SET_IS_COLLAPSE', false);
                this.isLeftOpen = true;
         }else{
                this.$store.commit('SET_IS_COLLAPSE', true);
                this.isLeftOpen = false;
         }
     },

对于this.$store.commit的写法有不理解的地方,建议可以去看下vuex

结束语

以上内容主要就是本次对动态加载可收缩菜单栏的讲解,如有不明之处可评论,github中会持续更新在项目中遇到的一些问题,谢谢!

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐