| // Licensed to the Apache Software Foundation (ASF) under one | |
| // or more contributor license agreements. See the NOTICE file | |
| // distributed with this work for additional information | |
| // regarding copyright ownership. The ASF licenses this file | |
| // to you under the Apache License, Version 2.0 (the | |
| // "License"); you may not use this file except in compliance | |
| // with the License. You may obtain a copy of the License at | |
| // | |
| // http://www.apache.org/licenses/LICENSE-2.0 | |
| // | |
| // Unless required by applicable law or agreed to in writing, | |
| // software distributed under the License is distributed on an | |
| // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | |
| // KIND, either express or implied. See the License for the | |
| // specific language governing permissions and limitations | |
| // under the License. | |
| 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) | |
| ) | |
| } | |
| } |