| import Menu from 'ant-design-vue/es/menu' |
| import Icon from 'ant-design-vue/es/icon' |
| |
| const { Item, SubMenu } = Menu |
| |
| export default { |
| name: 'SMenu', |
| props: { |
| menu: { |
| 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 { |
| openKeys: [], |
| selectedKeys: [], |
| cachedOpenKeys: [] |
| } |
| }, |
| computed: { |
| rootSubmenuKeys: vm => { |
| const keys = [] |
| vm.menu.forEach(item => keys.push(item.path)) |
| return keys |
| } |
| }, |
| created () { |
| this.updateMenu() |
| }, |
| watch: { |
| collapsed (val) { |
| if (val) { |
| this.cachedOpenKeys = this.openKeys.concat() |
| this.openKeys = [] |
| } else { |
| this.openKeys = this.cachedOpenKeys |
| } |
| }, |
| $route: function () { |
| this.updateMenu() |
| } |
| }, |
| methods: { |
| renderIcon: function (h, icon) { |
| if (icon === 'none' || icon === undefined) { |
| return null |
| } |
| const props = {} |
| typeof (icon) === 'object' ? props.component = icon : props.type = icon |
| return h(Icon, { props: { ...props } }) |
| }, |
| renderMenuItem: function (h, menu, pIndex, index) { |
| const target = menu.meta.target || null |
| return h(Item, { key: menu.path ? menu.path : 'item_' + pIndex + '_' + index }, [ |
| h('router-link', { attrs: { to: { name: menu.name }, target: target } }, [ |
| this.renderIcon(h, menu.meta.icon), |
| h('span', [menu.meta.title]) |
| ]) |
| ]) |
| }, |
| renderSubMenu: function (h, menu, pIndex, index) { |
| const this2_ = this |
| const subItem = [h('span', { slot: 'title' }, [this.renderIcon(h, menu.meta.icon), h('span', [menu.meta.title])])] |
| const itemArr = [] |
| const pIndex_ = pIndex + '_' + index |
| console.log('menu', menu) |
| if (!menu.hideChildrenInMenu) { |
| 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.hidden) { |
| return menu.children && !menu.hideChildrenInMenu |
| ? this.renderSubMenu(h, menu, pIndex, index) |
| : this.renderMenuItem(h, menu, pIndex, index) |
| } |
| }, |
| renderMenu: function (h, menuTree) { |
| const this2_ = this |
| const menuArr = [] |
| menuTree.forEach(function (menu, i) { |
| if (!menu.hidden) { |
| menuArr.push(this2_.renderItem(h, menu, '0', i)) |
| } |
| }) |
| return menuArr |
| }, |
| onOpenChange (openKeys) { |
| const latestOpenKey = openKeys.find(key => !this.openKeys.includes(key)) |
| if (!this.rootSubmenuKeys.includes(latestOpenKey)) { |
| this.openKeys = openKeys |
| } else { |
| this.openKeys = latestOpenKey ? [latestOpenKey] : [] |
| } |
| }, |
| updateMenu () { |
| const routes = this.$route.matched.concat() |
| |
| if (routes.length >= 4 && this.$route.meta.hidden) { |
| routes.pop() |
| this.selectedKeys = [routes[2].path] |
| } else { |
| this.selectedKeys = [routes.pop().path] |
| } |
| |
| const openKeys = [] |
| if (this.mode === 'inline') { |
| 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, |
| openKeys: this.openKeys, |
| selectedKeys: this.selectedKeys |
| }, |
| on: { |
| openChange: this.onOpenChange, |
| select: obj => { |
| this.selectedKeys = obj.selectedKeys |
| this.$emit('select', obj) |
| } |
| } |
| }, |
| this.renderMenu(h, this.menu) |
| ) |
| } |
| } |