feat: ✨ menu-header 和 menu-side 组件使用 jsx 重写 render
This commit is contained in:
@@ -1,32 +1,46 @@
|
|||||||
// 创建 el-menu-item
|
/**
|
||||||
|
* @description 创建菜单
|
||||||
|
* @param {Function} h createElement
|
||||||
|
* @param {Object} menu 菜单项
|
||||||
|
*/
|
||||||
export function elMenuItem (h, menu) {
|
export function elMenuItem (h, menu) {
|
||||||
return h('el-menu-item', { key: menu.path, props: { index: menu.path } }, [
|
let icon = null
|
||||||
...menu.icon ? [
|
if (menu.icon) icon = <i class={ `fa fa-${menu.icon}` }/>
|
||||||
h('i', { attrs: { class: `fa fa-${menu.icon}` } })
|
else if (menu.iconSvg) icon = <d2-icon-svg name={ menu.iconSvg }/>
|
||||||
] : [],
|
else icon = <i class="fa fa-file-o"/>
|
||||||
...menu.icon === undefined & !menu.iconSvg ? [
|
return <el-menu-item
|
||||||
h('i', { attrs: { class: 'fa fa-file-o' } })
|
key={ menu.path }
|
||||||
] : [],
|
index={ menu.path }>
|
||||||
...menu.iconSvg ? [
|
{ icon }
|
||||||
h('d2-icon-svg', { props: { name: menu.iconSvg } })
|
<span slot="title">{ menu.title || '未命名菜单' }</span>
|
||||||
] : [],
|
</el-menu-item>
|
||||||
h('span', { slot: 'title' }, menu.title || '未命名菜单')
|
|
||||||
])
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 创建 el-submenu
|
/**
|
||||||
|
* @description 创建子菜单
|
||||||
|
* @param {Function} h createElement
|
||||||
|
* @param {Object} menu 菜单项
|
||||||
|
*/
|
||||||
export function elSubmenu (h, menu) {
|
export function elSubmenu (h, menu) {
|
||||||
return h('el-submenu', { key: menu.path, props: { index: menu.path } }, [
|
let icon = null
|
||||||
...menu.icon ? [
|
if (menu.icon) icon = <i slot="title" class={ `fa fa-${menu.icon}` }/>
|
||||||
h('i', { slot: 'title', attrs: { class: `fa fa-${menu.icon}` } })
|
else if (menu.iconSvg) icon = <d2-icon-svg slot="title" name={ menu.iconSvg }/>
|
||||||
] : [],
|
else icon = <i slot="title" class="fa fa-folder-o"/>
|
||||||
...menu.icon === undefined & !menu.iconSvg ? [
|
return <el-submenu
|
||||||
h('i', { slot: 'title', attrs: { class: 'fa fa-folder-o' } })
|
key={ menu.path }
|
||||||
] : [],
|
index={ menu.path }>
|
||||||
...menu.iconSvg ? [
|
{ icon }
|
||||||
h('d2-icon-svg', { slot: 'title', props: { name: menu.iconSvg } })
|
<span slot="title">{ menu.title || '未命名菜单' }</span>
|
||||||
] : [],
|
{ menu.children.map(child => createMenu.call(this, h, child)) }
|
||||||
h('span', { slot: 'title' }, menu.title || '未命名菜单'),
|
</el-submenu>
|
||||||
...menu.children.map((child, childIndex) => (child.children === undefined ? elMenuItem : elSubmenu).call(this, h, child))
|
}
|
||||||
])
|
|
||||||
|
/**
|
||||||
|
* @description 在组件中调用此方法渲染菜单项目
|
||||||
|
* @param {Function} h createElement
|
||||||
|
* @param {Object} menu 菜单项
|
||||||
|
*/
|
||||||
|
export function createMenu (h, menu) {
|
||||||
|
if (menu.children === undefined) return elMenuItem.call(this, h, menu)
|
||||||
|
return elSubmenu.call(this, h, menu)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { throttle } from 'lodash'
|
import { throttle } from 'lodash'
|
||||||
import { mapState } from 'vuex'
|
import { mapState } from 'vuex'
|
||||||
import menuMixin from '../mixin/menu'
|
import menuMixin from '../mixin/menu'
|
||||||
import { elMenuItem, elSubmenu } from '../libs/util.menu'
|
import { createMenu } from '../libs/util.menu'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'd2-layout-header-aside-menu-header',
|
name: 'd2-layout-header-aside-menu-header',
|
||||||
@@ -9,41 +9,49 @@ export default {
|
|||||||
menuMixin
|
menuMixin
|
||||||
],
|
],
|
||||||
render (h) {
|
render (h) {
|
||||||
return h('div', {
|
return <div
|
||||||
attrs: { flex: 'cross:center' },
|
flex="cross:center"
|
||||||
class: { 'd2-theme-header-menu': true, 'is-scrollable': this.isScroll },
|
class={ { 'd2-theme-header-menu': true, 'is-scrollable': this.isScroll } }
|
||||||
ref: 'page'
|
ref="page">
|
||||||
}, [
|
<div
|
||||||
h('div', {
|
ref="content"
|
||||||
attrs: { class: 'd2-theme-header-menu__content', flex: '', 'flex-box': '1' },
|
class="d2-theme-header-menu__content"
|
||||||
ref: 'content'
|
flex-box="1"
|
||||||
}, [
|
flex>
|
||||||
h('div', {
|
<div
|
||||||
attrs: { class: 'd2-theme-header-menu__scroll', 'flex-box': '0' },
|
class="d2-theme-header-menu__scroll"
|
||||||
style: { transform: `translateX(${this.currentTranslateX}px)` },
|
flex-box="0"
|
||||||
ref: 'scroll'
|
style={ { transform: `translateX(${this.currentTranslateX}px)` } }
|
||||||
}, [
|
ref="scroll">
|
||||||
h('el-menu', {
|
<el-menu
|
||||||
props: { mode: 'horizontal', defaultActive: this.active },
|
mode="horizontal"
|
||||||
on: { select: this.handleMenuSelect }
|
defaultActive={ this.active }
|
||||||
}, this.header.map(menu => (menu.children === undefined ? elMenuItem : elSubmenu).call(this, h, menu)))
|
onSelect={ this.handleMenuSelect }>
|
||||||
])
|
{ this.header.map(menu => createMenu.call(this, h, menu)) }
|
||||||
]),
|
</el-menu>
|
||||||
...this.isScroll ? [
|
</div>
|
||||||
h('div', {
|
</div>
|
||||||
attrs: { class: 'd2-theme-header-menu__prev', flex: 'main:center cross:center', 'flex-box': '0' },
|
{
|
||||||
on: { click: () => this.scroll('left') }
|
this.isScroll
|
||||||
}, [
|
? [
|
||||||
h('i', { attrs: { class: 'el-icon-arrow-left' } })
|
<div
|
||||||
]),
|
class="d2-theme-header-menu__prev"
|
||||||
h('div', {
|
flex="main:center cross:center"
|
||||||
attrs: { class: 'd2-theme-header-menu__next', flex: 'main:center cross:center', 'flex-box': '0' },
|
flex-box="0"
|
||||||
on: { click: () => this.scroll('right') }
|
onClick={ () => this.scroll('left') }>
|
||||||
}, [
|
<i class="el-icon-arrow-left"></i>
|
||||||
h('i', { attrs: { class: 'el-icon-arrow-right' } })
|
</div>,
|
||||||
])
|
<div
|
||||||
] : []
|
class="d2-theme-header-menu__next"
|
||||||
])
|
flex="main:center cross:center"
|
||||||
|
flex-box="0"
|
||||||
|
onClick={ () => this.scroll('right') }>
|
||||||
|
<i class="el-icon-arrow-right"></i>
|
||||||
|
</div>
|
||||||
|
]
|
||||||
|
: []
|
||||||
|
}
|
||||||
|
</div>
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapState('d2admin/menu', [
|
...mapState('d2admin/menu', [
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { mapState } from 'vuex'
|
import { mapState } from 'vuex'
|
||||||
import menuMixin from '../mixin/menu'
|
import menuMixin from '../mixin/menu'
|
||||||
import { elMenuItem, elSubmenu } from '../libs/util.menu'
|
import { createMenu } from '../libs/util.menu'
|
||||||
import BScroll from 'better-scroll'
|
import BScroll from 'better-scroll'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
@@ -9,19 +9,25 @@ export default {
|
|||||||
menuMixin
|
menuMixin
|
||||||
],
|
],
|
||||||
render (h) {
|
render (h) {
|
||||||
return h('div', { attrs: { class: 'd2-layout-header-aside-menu-side' } }, [
|
return <div class="d2-layout-header-aside-menu-side">
|
||||||
h('el-menu', {
|
<el-menu
|
||||||
props: { collapse: this.asideCollapse, collapseTransition: this.asideTransition, uniqueOpened: true, defaultActive: this.$route.fullPath },
|
collapse={ this.asideCollapse }
|
||||||
ref: 'menu',
|
collapseTransition={ this.asideTransition }
|
||||||
on: { select: this.handleMenuSelect }
|
uniqueOpened={ true }
|
||||||
}, this.aside.map(menu => (menu.children === undefined ? elMenuItem : elSubmenu).call(this, h, menu))),
|
defaultActive={ this.$route.fullPath }
|
||||||
...this.aside.length === 0 && !this.asideCollapse ? [
|
ref="menu"
|
||||||
h('div', { attrs: { class: 'd2-layout-header-aside-menu-empty', flex: 'dir:top main:center cross:center' } }, [
|
onSelect={ this.handleMenuSelect }>
|
||||||
h('d2-icon', { props: { name: 'inbox' } }),
|
{ this.aside.map(menu => createMenu.call(this, h, menu)) }
|
||||||
h('span', {}, '没有侧栏菜单')
|
</el-menu>
|
||||||
])
|
{
|
||||||
] : []
|
this.aside.length === 0 && !this.asideCollapse
|
||||||
])
|
? <div class="d2-layout-header-aside-menu-empty" flex="dir:top main:center cross:center">
|
||||||
|
<d2-icon name="inbox"></d2-icon>
|
||||||
|
<span>没有侧栏菜单</span>
|
||||||
|
</div>
|
||||||
|
: null
|
||||||
|
}
|
||||||
|
</div>
|
||||||
},
|
},
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
|
|||||||
Reference in New Issue
Block a user