iview可收缩侧边菜单实现(支持二级菜单)
想用iview做一个可以伸缩的侧边菜单栏,效果如下:
1.侧边栏收缩前:可以通过点击菜单分类展开子菜单项;
2.可以让用户点击图标动态收缩菜单栏;
3.侧边栏收缩后:只显示菜单分类的图标,鼠标放置在菜单分类上后右侧展示子菜单项目。
一、初探
仔细看了iview的菜单组件,菜单组件本身不支持伸缩(element UI、antd是有现成组件的),看了一下layout组件(https://www.iviewui.com/components/layout)可以实现动态收缩侧边栏(侧边栏伸缩同时隐藏菜单项的文字实现菜单收缩)。但这种方法只是单纯的将一级分类菜单隐藏了,示例中是只有一级菜单,自己套入二级菜单后惨不忍睹。
二、研究思考
百度了一堆iview伸缩菜单的实现方式,发现有的人在侧边栏收缩后二级菜单能正常显示,心里就想莫非这些人是用是收费的UI Pro,于是就打开了UI Pro的网址(https://pro.iviewui.com/pro/introduce)。你猜怎么着!Pro的网站侧边栏就是我们想要的效果,翻了一下Pro的组件也没有可伸缩的菜单组件啊~ 看来只能自己实现了,不过好在可以拿Pro的的做参考研究。
观察发现侧边栏收起来后:1)当菜单分类下没有子菜单时,右边弹出的是一个tooltip组件 2)当菜单分类下有子菜单时,右边弹出的是dropdown组件。
三、实现
将菜单放到menu数组中,通过children属性设置菜单分类的子菜单,template部分对menu进行遍历,通过判断当前条件(侧边栏是否收缩、当前分类是否有子菜单)放置不同的组件,实现侧边菜单的动态伸缩展示。存在如下4种情况:
1.菜单展开时,当前菜单分类没有子菜单,使用MenuItem组件。
2.菜单展开时,当前菜单分类有子菜单,使用Submenu组件。
3.菜单收缩时,当前菜单没有子菜单,使用Tooltip组件。
4.菜单收缩时,当前菜单有子菜单,使用Dropdown组件。
template部分代码如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | <Menu active-name= "home" :open-names= "['home']" :theme= "menuTheme" width= "auto" : class = "menuitemClasses" accordion > <template v- for = "(item, componentIndex) in menu" > <!-- 展开并且有子菜单 --> <Submenu v- if = "!isCollapsed && item.children.length" v-bind:key= "componentIndex" :name= "componentIndex" > <template slot= "title" > <Icon :type= "item.icon" /> <span>{{ item.name }}</span> </template> <MenuItem v- for = "(children, index) in item.children" :key= "index" :name= "children.to" :to= "children.to" > {{ children.name }} </MenuItem> </Submenu> <!-- 展开但没有子菜单 --> <MenuItem v- else - if = "!isCollapsed" :name= "item.to" :to= "item.to" v-bind:key= "componentIndex" > <Icon :type= "item.icon" /> <span>{{ item.name }}</span> </MenuItem> <!-- 不展开有子菜单 --> <Dropdown v- else - if = "isCollapsed && item.children.length" v-bind:key= "componentIndex" placement= "right-start" class = "menu-dropdown" > <MenuItem :name= "item.to" :to= "item.to" > <Icon :type= "item.icon" /> <span>{{ item.name }}</span> </MenuItem> <DropdownMenu slot= "list" > <DropdownItem v- for = "(children, index) in item.children" :key= "index" style= "padding: 0 0; background-color:#515a6e;" > <MenuItem :name= "children.to" :to= "children.to" >{{ children.name }}</MenuItem> </DropdownItem> </DropdownMenu> </Dropdown> <!-- 不展开无子菜单 --> <Tooltip v- else - if = "isCollapsed" :content= "item.name" placement= "right" v-bind:key= "componentIndex" > <MenuItem :name= "item.to" :to= "item.to" > <Icon :type= "item.icon" /> <span>{{ item.name }}</span> </MenuItem> </Tooltip> </template> </Menu> |
data部分菜单定义代码如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | data() { return { isCollapsed: false , keepAliveList: [], title: "Home" , showSettingPage: false , showSuggestionPage: false , menu: [ { name: "主页" , to: "home" , icon: "md-apps" , children: [] }, { name: "菜单分类1" , to: "user" , icon: "ios-create-outline" , children: [ { name: "子菜单1" , to: "user" }, { name: "子菜单2" , to: "menu" }, { name: "子菜单3" , to: "shared_report" }, ] }, { name: "菜单分类2" , to: "user2" , icon: "ios-archive-outline" , children: [ { name: "子菜单2-1" , to: "firewall" }, { name: "子菜单2-2" , to: "navi_page" } ] } ] }; }, |
四、优化
能够看到这里,说明你也是个前端高手。当侧边栏收缩时,还有如下几个优化项大概提一下,给个方向:
1.dropdown menu背景颜色与侧边栏不一致。
2.dropdown menu上放置鼠标后,有其他颜色出现。—— menuItem的li元素有padding
3.dropdown menu显示区域与侧边菜单有重叠。—— dropdown menu中的ivu-dropdown-rel宽度没有完全占满父元素导致,可以通过设置有宽度的透明的右边框解决。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步