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.
138 lines
3.5 KiB
138 lines
3.5 KiB
/** |
|
* 该插件可根据菜单配置自动生成 ANTD menu组件 |
|
* menuData示例: |
|
* [ |
|
* { |
|
* title: '菜单标题', |
|
* icon: '菜单图标', |
|
* path: '菜单路由', |
|
* invisible: 'boolean, 是否不可见', |
|
* children: [子菜单配置] |
|
* }, |
|
* { |
|
* title: '菜单标题', |
|
* icon: '菜单图标', |
|
* path: '菜单路由', |
|
* invisible: 'boolean, 是否不可见', |
|
* children: [子菜单配置] |
|
* } |
|
* ] |
|
**/ |
|
import Menu from 'vue-antd-ui/es/menu' |
|
import Icon from 'vue-antd-ui/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' |
|
} |
|
}, |
|
data () { |
|
return { |
|
rootSubmenuKeys: ['/form', '/list', '/detail', '/exception', '/result'], |
|
openKeys: [] |
|
} |
|
}, |
|
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] : [] |
|
} |
|
} |
|
}, |
|
render (h) { |
|
return h( |
|
Menu, |
|
{ |
|
props: { |
|
theme: this.$props.theme, |
|
mode: this.$props.mode, |
|
inlineCollapsed: false, |
|
openKeys: this.openKeys |
|
}, |
|
on: { |
|
openChange: this.onOpenChange |
|
} |
|
}, this.renderMenu(h, this.menuData) |
|
) |
|
} |
|
}
|
|
|