vue+antd 后台管理框架
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

176 lines
4.4 KiB

/**
* 该插件可根据菜单配置自动生成 ANTD menu组件
* menuData示例
* [
* {
* title: '菜单标题',
* icon: '菜单图标',
* path: '菜单路由',
* invisible: 'boolean, 是否不可见',
* children: [子菜单配置]
* },
* {
* title: '菜单标题',
* icon: '菜单图标',
* path: '菜单路由',
* invisible: 'boolean, 是否不可见',
* children: [子菜单配置]
* }
* ]
**/
import Menu from 'ant-design-vue/es/menu'
import Icon from 'ant-design-vue/es/icon/icon'
const {Item, SubMenu} = Menu
// 默认菜单图标数组,如果菜单没配置图标,则会设置从该数组随机取一个图标配置
const iconArr = ['dashboard', 'user', 'form', 'setting', 'message', 'safety', 'bell', 'delete', 'code-o', 'poweroff', 'eye-o', 'hourglass']
export default {
name: 'IMenu',
props: {
menuData: {
type: Array,
required: true
},
theme: {
type: String,
required: false,
default: 'dark'
},
mode: {
type: String,
required: false,
default: 'inline'
},
collapsed: {
type: Boolean,
required: false,
default: false
}
},
data () {
return {
7 years ago
rootSubmenuKeys: ['/dashboard', '/form', '/list', '/detail', '/exception', '/result'],
7 years ago
openKeys: [],
selectedKeys: [],
7 years ago
cachedOpenKeys: []
}
},
created () {
this.updateMenu()
},
watch: {
collapsed (val) {
if (val) {
7 years ago
this.cachedOpenKeys = this.openKeys
this.openKeys = []
7 years ago
} else {
this.openKeys = this.cachedOpenKeys
}
},
'$route': function () {
this.updateMenu()
}
},
methods: {
renderIcon: function (h, icon) {
return icon === 'none' ? null
: h(
Icon,
{
props: {type: icon !== undefined ? icon : iconArr[Math.floor((Math.random() * iconArr.length))]}
})
},
renderMenuItem: function (h, menu, pIndex, index) {
return h(
Item,
{
key: menu.path ? menu.path : 'item_' + pIndex + '_' + index
},
[
h(
'a',
{attrs: {href: '#' + menu.path}},
[
this.renderIcon(h, menu.icon),
h('span', [menu.name])
]
)
]
)
},
renderSubMenu: function (h, menu, pIndex, index) {
var this2_ = this
var subItem = [h('span',
{slot: 'title'},
[
this.renderIcon(h, menu.icon),
h('span', [menu.name])
]
)]
var itemArr = []
var pIndex_ = pIndex + '_' + index
menu.children.forEach(function (item, i) {
itemArr.push(this2_.renderItem(h, item, pIndex_, i))
})
return h(
SubMenu,
{key: menu.path ? menu.path : 'submenu_' + pIndex + '_' + index},
subItem.concat(itemArr)
)
},
renderItem: function (h, menu, pIndex, index) {
if (!menu.invisible) {
return menu.children ? this.renderSubMenu(h, menu, pIndex, index) : this.renderMenuItem(h, menu, pIndex, index)
}
},
renderMenu: function (h, menuTree) {
var this2_ = this
var menuArr = []
menuTree.forEach(function (menu, i) {
menuArr.push(this2_.renderItem(h, menu, '0', i))
})
return menuArr
},
onOpenChange (openKeys) {
const latestOpenKey = openKeys.find(key => this.openKeys.indexOf(key) === -1)
if (this.rootSubmenuKeys.indexOf(latestOpenKey) === -1) {
this.openKeys = openKeys
} else {
this.openKeys = latestOpenKey ? [latestOpenKey] : []
}
},
updateMenu () {
let routes = this.$route.matched.concat()
this.selectedKeys = [routes.pop().path]
let openKeys = []
routes.forEach((item) => {
openKeys.push(item.path)
})
this.collapsed ? this.cachedOpenKeys = openKeys : this.openKeys = openKeys
}
},
render (h) {
return h(
Menu,
{
props: {
theme: this.$props.theme,
mode: this.$props.mode,
inlineCollapsed: false,
openKeys: this.openKeys,
selectedKeys: this.selectedKeys
},
on: {
openChange: this.onOpenChange,
select: (obj) => {
this.selectedKeys = obj.selectedKeys
this.$emit('select', obj)
}
}
}, this.renderMenu(h, this.menuData)
)
}
}