iView Admin的side menu改为top menu

和iView Admin结缘于某次在"顾问群"里问,"有什么开源前端框架推荐吗?"。群里一位老开发答,"试试iView Admin"。于是我就试了试,发现很好用,对新手也很友好,试过撸一个管理后台的前端用了4天,感觉效率还可以。

最近需要定制"无侧滑菜单,改用顶部下拉菜单"的效果,所以开始分析下源码。

看/src/router/router.js里原始定义的路由,可以看到首页路由使用的component是Main。


image.png

然后我们打开component/main.vue来查看,如下图。可以看到main.vue相当于一个大框架底层页面,页面结构可以简单分为Sider(左侧展开的菜单)、Header(顶部)以及Content(主要内容区)。把Sider注释或者删除,就相当于实现了"无侧滑菜单"的效果。然后看下Header里的组件,分别有HeaderBar、user、language、error-store、fullscreen,看来这个headerbar就是我们可以添加"下拉菜单"的地方了。


image.png

原来的header-bar.vue如下。

复制代码
<template>
  <div class="header-bar">
    <sider-trigger :collapsed="collapsed" icon="md-menu" @on-change="handleCollpasedChange"></sider-trigger>
    <custom-bread-crumb show-icon style="margin-left: 30px;" :list="breadCrumbList"></custom-bread-crumb>
    <div class="custom-content-con">
      <slot></slot>
    </div>
  </div>
</template>

可以看到这个HeaderBar里有两个组件,一个是点击一下就触发左侧菜单弹出、并且自身Icon发生旋转的sider-trigger,另一个就是自定义的面包屑导航custom-bread-crumb。于是想到,把这里的sider-trigger替换成我们即将写好的下拉菜单组件,传入菜单数据以及对下拉菜单的点击事件进行捕捉后,调用原来的gotoPage的方法,应该就能满足需求了。

我们先去写下拉菜单组件collapse-menu.vue。根据iView Admin原来的route元组的构成方式,使用DropdownMenu组件来展示不同层级的菜单。showTitle是根据当前route元组中的name以及当前locale显示出对应的文字,最后完成的collase-menu的template部分如下:

collapse-menu.vue

复制代码
<template>
  <Dropdown ref="dropdown" @on-click="handleClick">
    <a href="javascript:void(0)">
      <Icon type="md-menu" size="26"></Icon>
    </a>
    <DropdownMenu slot="list">
      <template v-for="item in menuList">
        <DropdownItem v-if="!showChildren(item) && (!item.meta || (item.meta && !item.meta.hideInMenu))"
        :name="getNameOrHref(item,true)"
        >
        {{showTitle(item)}}</DropdownItem>
        <Dropdown v-if="showChildren(item) && (!item.meta || (item.meta && !item.meta.hideInMenu))" :placement="placement">
          <DropdownItem>{{showTitle(item)}}
            <Icon type="ios-arrow-forward"></Icon>
          </DropdownItem>
          <DropdownMenu slot="list">
                   <DropdownItem v-for ="subItem in item.children"
                   v-if=" !subItem.meta || (subItem.meta && !subItem.meta.hideInMenu)" 
                   :name="getNameOrHref(subItem)"
                    >{{showTitle(subItem)}}</DropdownItem>
          </DropdownMenu>
        </Dropdown>
      </template>
    </DropdownMenu>
  </Dropdown>
</template>

此外该组件里还需要增加一个用于判断该route元组是使用vue页面还是外部页面,如果是外部页面,则往上回传的应该是带有标记的外部url, 这样在main.vue里的turnToPage的方法,就可以直接使用组件事件回传的参数进行跳转。关键代码如下:

复制代码
getNameOrHref (item,children0) {
     return item.href ? `isTurnByHref_${item.href}` : (children0 ? item.children[0].name : item.name)
    },

然后,就可以在Header-bar.vue里直接引用新做好的下拉菜单组件了。header-bar.vue中的template部分如下:

复制代码
<template>
  <div class="header-bar">
    <CollapsedMenu :menuList="menuList" @on-click="handleSelect"/>
    <custom-bread-crumb show-icon  :list="breadCrumbList"></custom-bread-crumb>
    <div class="custom-content-con">
      <slot></slot>
    </div>
  </div>
</template>

然后在main.vue里,将所需的菜单数据传给header-bar,再由header-bar依次传递。

main.vue

复制代码
<Header class="header-con">
        <header-bar :collapsed="collapsed" @on-coll-change="handleCollapsedChange" :menu-list="menuList" @on-select="turnToPage">
          <user :user-avator="userAvator" :userName="userName"/>
          <language v-if="$config.useI18n" @on-lang-change="setLocal" style="margin-right: 10px;" :lang="local"/>
          <error-store v-if="$config.plugin['error-store'] && $config.plugin['error-store'].showInHeader" :has-read="hasReadErrorPage" :count="errorCount"></error-store>
          <fullscreen v-model="isFullscreen" style="margin-right: 10px;"/>
        </header-bar>
      </Header>

最后总结下本次实现过程中父子组件间涉及到的通信:

1.父组件往子组件传数据,用的是props这个单向数据流的方式,将menuList传到最终的子组件。

2.子组件往父组件传值,用的是$emit,将子组件里click/change事件触发时的值,会传到父组件。
最后编辑于:2025-04-21 10:54:09
© 著作权归作者所有,转载或内容合作请联系作者

喜欢的朋友记得点赞、收藏、关注哦!!!

相关推荐
码兄科技4 小时前
Java AI智能体开发实战:从零构建智能对话系统指南
java·开发语言·人工智能
折哥的程序人生 · 物流技术专研4 小时前
第8篇:六大设计原则在工厂模式中的体现
java·设计模式·设计原则·工厂模式·编程进阶·扩充系列
小明bishe185 小时前
计算机毕业设计之基于JAVA的植物科普网站
java·spring boot·spring·架构·课程设计
r_oo_ki_e_5 小时前
Java Map 集合学习笔记
java·笔记·学习
SL-staff5 小时前
智慧园区2000+设备统一管理:JVS-IoT如何降低运维成本40%
java·开发语言·物联网·智慧园区·设备管理·运维优化·jvs-iot
咖啡八杯6 小时前
GoF设计模式——模板方法模式
java·后端·spring·设计模式
爱笑的源码基地7 小时前
一款全开源的信创云PACS影像云平台解决方案,支持多模态医学影像处理(CT/MR/DR/超声/病理等)
java·源码·国产化·pacs·云影像·区域pacs
我命由我123457 小时前
Android 开发问题:ClickableSpan 的点击事件没有生效
java·java-ee·android studio·android jetpack·android-studio·android runtime
万亿少女的梦1687 小时前
基于Python的高考志愿填报辅助系统设计与实现
java·spring boot·python·mysql·vue
万亿少女的梦1687 小时前
基于SpringBoot与Vue的历史博物馆展品展示与游客管理系统设计
spring boot·mysql·vue·系统设计·博物馆管理系统