本文主要是介绍动态渲染 Element UI el-menu 组件,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
相信大家在使用 Element UI 中 el-menu 组件的时候,都碰到过如何通过数据动态渲染的问题,而官方的文档却没有这个实例,网上找的一些博客大部分人都实现了 el-menu 的垂直模式,而水平模式却没有,并且垂直模式的 el-menu 在收缩的时候会出现问题,但是他们并没有去解决,让我很苦恼,没办法,只能自己去解决了,先给大家看看效果先:
如上所示,水平和垂直模式的el-menu都一实现,而且垂直的el-menu收缩也正常,下面给大家贴上代码:
水平 el-menu
水平模式的el-menu主要分为两个js文件:
- ch-horizonal-menu.js
- ch-horizonal-menu-item.js
ch-horizonal-menu.js
;(function (root , factory) {if(typeof exports === 'object') {module.exports = exports = factory();} else if(typeof define === 'function' && define.amd) {define([] , factory());} else {root.chHorizonalMenu = factory();}
})(this , function () {let chHorizonalMenu = {template:'<ul class="ch-horizonal-menu" :style="{backgroundColor:backgroundColor}">'+'<ch-horizonal-menu-item '+':menus="data" '+':active-text-color="activeTextColor"'+':background-color="backgroundColor"'+':activeId="activeId"'+'@item-click="itemClick">'+'</ch-horizonal-menu-item>'+'</ul>',props:{data:{type:Array , default:function () {return []}},backgroundColor:{type:String,default:'rgb(46, 50, 61)'},activeTextColor:{type:String,default:'rgb(255, 208, 75)'}},data:function () {return {activeId:null,submenuIds:[]}},methods:{itemClick:function (params) {this.activeId = params.id;this.removeActive();this.$emit('item-click' , params);},removeActive:function () {var _this = this ;var activeNodes = this.$el.getElementsByClassName('is_active');[].slice.call(activeNodes).forEach(function (el) {el.className = el.className.replace(/ is_active/ , '');el.style.color = '#fff';})}}}return {name:'ch-horizonal-menu',template:chHorizonalMenu}
})
ch-horizonal-menu-item.js
;(function (root , factory) {if(typeof exports === 'object') {module.exports = exports = factory();} else if(typeof define === 'function' && define.amd) {define([] , factory());} else {root.chHorizonalMenuItem = factory();}
})(this , function () {let chHorizonalMenuItem = {template:'<div>'+'<template v-for = "menu in menus">'+'<li v-if="menu.children && menu.children.length" '+'@mouseenter="onMouseEnter($event , menu.id)"'+'@mouseleave="onMouseLeave($event)"'+'class="ch-horizonal-menu-item ch-horizonal-submenu">'+'<div class="ch-horizonal-submenu__title">'+'<span>{{menu.name}}</span>'+'<i :class=\'[ floor == 1 ? "el-icon-arrow-down" : "el-icon-arrow-right", "ch-horizonal-submenu__icon-arrow"]\'></i>'+'</div>'+'<div class="ch-horizonal-submenu_inner" v-show="current_id == menu.id">'+'<ul class="ch-horizonal-menu__inner" '+':style="{backgroundColor:backgroundColor}">'+'<ch-horizonal-menu-item '+':menus="menu.children" '+':active-text-color="activeTextColor"'+':background-color="backgroundColor"'+':activeId="activeId"'+':level="floor" '+'@item-click="itemClick">'+'</ch-horizonal-menu-item>'+'</ul>'+'</div>'+'</li>'+'<li v-else '+':style="{color:activeId == menu.id ? activeTextColor :\'#fff\' }"'+'class="ch-horizonal-menu-item"'+'@click="itemClick(menu , $event)">{{menu.name}}</li>'+'</template>'+'</div>',props:{menus:{type: Array,default: function () {return [];}},level:{type: Number,default:0},activeId:{type:[Number , String],default:''},activeTextColor:String,backgroundColor:String},data:function () {return {show:false,floor:this.level,timeId:0,current_id:-1,isActive:false}},created:function () {this.floor++;},methods:{onMouseEnter:function (event , id) {clearTimeout(this.timeId);this.current_id = id ;this.$nextTick(function () {if(this.floor > 1) {var innerMenu = event.target.querySelector('.ch-horizonal-menu__inner');var innerMenuItem = event.target.querySelector('.ch-horizonal-menu-item');innerMenu.style.left = (innerMenuItem.offsetWidth - 20 + 5) + 'px';innerMenu.style.top = (-innerMenuItem.offsetHeight) + 'px';}})},onMouseLeave:function (event) {this.timeId = setTimeout(function () {this.current_id = -1 ;}.bind(this) , 200)},itemClick:function (menu , event) {this.current_id = -1 ;this.$emit('item-click' , menu);if(event) this.setParentNodeActive(event.target.parentNode , 'ch-horizonal-submenu');},setParentNodeActive:function (el , cls) {var classList = el.className.split(' ');if(classList.indexOf('ch-horizonal-menu') == -1) {if(classList.indexOf(cls) != -1) {el.style.color = this.activeTextColor;el.className = el.className.concat(' is_active');}this.setParentNodeActive(el.parentNode , cls);}}}}return {name:'ch-horizonal-menu-item',template:chHorizonalMenuItem}
})
使用示例
// 注册 chHorizonalMenuItem 必须在 chHorizonalMenu 前注册Vue.component(chHorizonalMenuItem.name , chHorizonalMenuItem.template);Vue.component(chHorizonalMenu.name , chHorizonalMenu.template);<ch-horizonal-menu :data="menus"background-color="#1B75D5"@item-click="onHorizonalMenuClick"></ch-horizonal-menu>
垂直 el-menu
ch-vertical-menu-item.js
;(function (root , factory) {if(typeof exports === 'object') {module.exports = exports = factory();} else if(typeof define === 'function' && define.amd) {define([] , factory());} else {root.chVerticalMenuItem = factory();}
})(this , function () {var chVerticalMenuItem = {template:'<div class="ch-menu-wrapper">'+'<template v-for="menu in data">'+'<el-menu-item v-if="!menu.children" :index="menu.id" @click="handleMenuItem(menu)"> '+'<i v-if="menu.icon" :class="menu.icon"></i>'+'<span slot="title">{{menu.name}}</span>'+'</el-menu-item>'+'<el-submenu v-else :index="menu.id">'+'<template slot="title">'+'<i v-if="menu.icon" :class="menu.icon"></i>'+'<span>{{menu.name}}</span>'+'</template>'+'<ch-vertical-menu-item :data="menu.children" @item-click="onMenuClick"></ch-vertical-menu-item>'+'</el-submenu>'+'</template>'+'</div> ',props:{data:{type:Array,default:function () {return [] ;}}},methods:{handleMenuItem:function (menu) { this.$emit("item-click" , menu);},onMenuClick:function (menu) {this.$emit("item-click" , menu);}}}return {name:'ch-vertical-menu-item',template:chVerticalMenuItem}
})
使用示例
// 注册Vue.component(chVerticalMenuItem.name , chVerticalMenuItem.template);<el-menu:default-active="activeMenuId":background-color="themeColor"text-color="#fff":collapse="isCollapse"class="el-menu-vertical-left"active-text-color="#ffd04b"><ch-vertical-menu-item :data="menus" @item-click="onCHMenuClick"></ch-vertical-menu-item></el-menu>
由于垂直模式的 el-menu 只是用 Element UI原生组件进行再封装,所以相关配置请参考其文档,而水平模式的 el-menu 则是自定义的组件,因此两者没有封装到一起,用法上也有所不同,还请各位见谅!
完整代码请查看 vue-web-frame 导航菜单示例
这篇关于动态渲染 Element UI el-menu 组件的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!