简约菜单都可以使用el-menu
生成,水平的菜单或者垂直的菜单。
本文是希望能帮助需求者更快熟悉el-menu
的使用,以及传入菜单项能快速生成n级菜单。
基础介绍
使用的时候,最外层是el-menu
,其上面属性,是用来配置整个菜单,如水平还是垂直、背景色、文字色、默认激活的菜单子项、默认展开的菜单子项等。
el-menu
的子元素只有三种情况:
- el-menu-item 就是普通的菜单项
- el-submenu 是菜单项里还有子菜单
- el-menu-item-group 是菜单项组,就是好几个菜单项有个标题
index的妙用
建议将每个el-menu-item
和el-submenu
上加上index
的属性。
好处以下:
- 选中的时候,有高亮的状态
- 方便设置默认选中的菜单,可以
default-active='anyIndex'
- 方便设置默认展开的嵌套菜单,可以
:default-openeds='["submenuIndex"]'
,这里必须是数组哈 - 点击
el-menu-item
触发select事件,可以知道选了哪个和路径数组 - 点击
el-submenu
触发open/close事件,可以知道选了哪个和路径数组 el-menu
设置router
属性的时候,index作为 path 进行路由跳转
折叠菜单
一级菜单每个加特定的图标,然后就可以折叠,这样最大化内容区。
折叠使用的是el-menu
的collapse
属性。但记得将文字用标签裹起来,且加上slot='title'
,这样框架本身将title
会隐藏起来,且在hover
的时候显示出来。
重点来了:生成菜单
先简单点,只有二级菜单。 data增加menus,然后将模板部分,该循环循环,该判断判断,常量的地方变成变量。
生成n级菜单,肯定递归哈
如果没有写过递归组件的,可以尝试先写下三级菜单。
然后将重复的地方,提出来作为一个组件就可以了。
递归组件,需要多思考,多敲哈~
提取出来的MiddleMenu
如下:
抽离出菜单组件,传入菜单项配置自动生成菜单
这里就是把data
里的menus
变成传参,然后将el-menu
再包装一层,巧妙的用下$attrs
和$listeners
。
使用的时候
create-menu(:menus='menus' default-active='xx' style='width:210px' @select='handleSelect')
水平菜单和其他属性
如果觉得还需要什么功能,优先去官网看看。
- 想要水平菜单:
mode='horizontal'
- 想设置菜单的背景色、文字色、激活菜单的文字色(夜间模式):
background-color="#545c64" text-color="#fff" active-text-color="#ffd04b"
- 只想有一个子菜单展开:
unique-opened
- 打开子菜单的方式可以设置hover:
menu-trigger='hover'
- 不要折叠的动画效果:
:collapse-transition='false'
- 点击菜单项直接去相应的路由:
router
,且相应的index设置成路由路径
附注代码
最近试着手写实现el-menu组件,有兴趣可以看下
基础介绍代码
section(style='width:210px')
el-menu
el-menu-item 单项菜单1
el-menu-item 单项菜单2
el-submenu
template(slot='title') 有子菜单,带展开小箭头
el-menu-item 子菜单1
el-menu-item 子菜单2
el-menu-item-group(title='菜单组,直接展开')
el-menu-item 组员1
el-menu-item 组员2
加index代码
<template lang='pug'>
section(style='width:210px')
el-menu(default-active='menu1' :default-openeds='["submenu1"]'
@open='handleOpen' @close='handleClose' @select='handleSelect')
el-menu-item(index='menu1') 单项菜单1
el-menu-item(index='menu2') 单项菜单2
el-submenu(index='submenu1')
template(slot='title') 有子菜单,带展开小箭头
el-menu-item(index='menu1-1') 子菜单1
el-menu-item(index='menu1-2') 子菜单2
el-menu-item-group(title='菜单组,直接展开')
el-menu-item(index='menu3') 组员1
el-menu-item(index='menu4') 组员2
</template>
<script>
export default {
methods: {
handleOpen (key, keyPath) {
console.log('open事件', key, keyPath)
},
handleClose (key, keyPath) {
console.log('close事件', key, keyPath)
},
handleSelect (key, keyPath) {
console.log('select事件', key, keyPath)
}
}
}
</script>
折叠菜单代码
<template lang='pug'>
section(style='width:210px')
el-menu.el-menu-vertical-demo(default-active='menu1' :collapse='isCollapse')
el-menu-item(index='menu1')
i.el-icon-location
span(slot='title') 单项菜单1
el-menu-item(index='menu2')
i.el-icon-document
span(slot='title') 单项菜单2
el-submenu(index='submenu1')
template(slot='title')
i.el-icon-setting
span(slot='title') 有子菜单
el-menu-item(index='menu1-1') 子菜单1
el-menu-item(index='menu1-2') 子菜单2
div(style='margin-top:20px')
el-button(@click='isCollapse=!isCollapse') {{isCollapse?'展开':'折叠'}}
</template>
<script>
export default {
data () {
return {
isCollapse: true
}
}
}
</script>
生成菜单,只有二级代码
<template lang='pug'>
section(style='width:210px')
el-menu.el-menu-vertical-demo(default-active='首页' :collapse='isCollapse')
template(v-for='(item,outerIndex) in menus' )
el-submenu(v-if='item.children' :index='item.text' :key='outerIndex')
template(slot='title')
i(:class='item.iconClass')
span(slot='title') {{item.text}}
el-menu-item(v-for='(innerItem,innerIndex) in item.children' :key='innerIndex'
:index='innerItem.text') {{innerItem.text}}
el-menu-item(v-else :index='item.text' :key='outerIndex')
i(:class='item.iconClass')
span(slot='title') {{item.text}}
div(style='margin-top:20px')
el-button(@click='isCollapse=!isCollapse') {{isCollapse?'展开':'折叠'}}
</template>
<script>
export default {
data () {
let menus = [
{ text: '首页', iconClass: 'el-icon-document' },
{ text: '人员管理', iconClass: 'el-icon-user', children: [ { text: '教师管理' }, { text: '助教管理' } ] },
{ text: '权限管理', iconClass: 'el-icon-setting', children: [ { text: '角色管理' }, { text: '人员角色' } ] }
]
return {
isCollapse: false,
menus
}
}
}
</script>
生成n级菜单代码
<!-- MiddleMenu.vue -->
<template lang="pug">
//- 这里注意不能使用div包裹,因为menu的标签很多是li,不能使用别的标签,所以使用component
component(:is='menuItem.children?"el-submenu":"el-menu-item"' :index='menuItem.text')
template(v-if='menuItem.children')
template(slot='title')
i(:class='menuItem.iconClass')
span(slot='title') {{menuItem.text}}
//- 和Index重复的地方,这也是递归的关键
template(v-for='(innerItem,innerIndex) in menuItem.children')
middle-menu(:menu-item='innerItem' :key='innerIndex')
template(v-else)
i(:class='menuItem.iconClass')
span(slot='title') {{menuItem.text}}
</template>
<script>
export default {
name: 'middle-menu',
props: {
menuItem: {
type: Object,
required: true
}
}
}
</script>
<!-- Index.vue -->
<template lang='pug'>
section(style='width:210px')
el-menu.el-menu-vertical-demo(default-active='首页' :collapse='isCollapse')
//- 和MiddleMenu重复的地方
template(v-for='(item,outerIndex) in menus' )
middle-menu( :menu-item='item' :key='outerIndex')
div(style='margin-top:20px')
el-button(@click='isCollapse=!isCollapse') {{isCollapse?'展开':'折叠'}}
</template>
<script>
import MiddleMenu from './components/MiddleMenu'
export default {
components: { MiddleMenu },
data () {
let menus = [
{ text: '首页', iconClass: 'el-icon-document' },
{ text: '人员管理',
iconClass: 'el-icon-user',
children: [ { text: '教师管理', children: [{ text: '数学系' }] }, { text: '助教管理' } ] },
{ text: '权限管理',
iconClass: 'el-icon-setting',
children: [ { text: '角色管理' }, { text: '人员角色' } ] }
]
return {
isCollapse: false,
menus
}
}
}
</script>
抽离出来的菜单组件
<!-- CreateMenu.vue -->
<template lang='pug'>
el-menu(v-bind='$attrs' v-on='$listeners')
template(v-for='(item,outerIndex) in menus' )
middle-menu(:menu-item='item' :key='outerIndex')
</template>
<script>
import MiddleMenu from './MiddleMenu'
export default {
components: { MiddleMenu },
props: {
menus: {
type: Array,
required: true
}
}
}
</script>