inleft
2022-02-15 d734432a8bbbf863dc3de305f56e831c56ac767a
commit | author | age
9bcb19 1 import Menu from 'ant-design-vue/es/menu'
I 2 import Icon from 'ant-design-vue/es/icon'
3
4 const { Item, SubMenu } = Menu
5
6 export default {
7   name: 'SMenu',
8   props: {
9     menu: {
10       type: Array,
11       required: true
12     },
13     theme: {
14       type: String,
15       required: false,
16       default: 'dark'
17     },
18     mode: {
19       type: String,
20       required: false,
21       default: 'inline'
22     },
23     collapsed: {
24       type: Boolean,
25       required: false,
26       default: false
27     }
28   },
29   data () {
30     return {
31       openKeys: [],
32       selectedKeys: [],
33       cachedOpenKeys: []
34     }
35   },
36   computed: {
37     rootSubmenuKeys: vm => {
38       const keys = []
39       vm.menu.forEach(item => keys.push(item.path))
40       return keys
41     }
42   },
43   created () {
44     this.updateMenu()
45   },
46   watch: {
47     collapsed (val) {
48       if (val) {
49         this.cachedOpenKeys = this.openKeys.concat()
50         this.openKeys = []
51       } else {
52         this.openKeys = this.cachedOpenKeys
53       }
54     },
55     $route: function () {
56       this.updateMenu()
57     }
58   },
59   methods: {
60     renderIcon: function (h, icon) {
61       if (icon === 'none' || icon === undefined) {
62         return null
63       }
64       const props = {}
65       typeof (icon) === 'object' ? props.component = icon : props.type = icon
66       return h(Icon, { props: { ...props } })
67     },
68     renderMenuItem: function (h, menu, pIndex, index) {
69       const target = menu.meta.target || null
70       return h(Item, { key: menu.path ? menu.path : 'item_' + pIndex + '_' + index }, [
71         h('router-link', { attrs: { to: { name: menu.name }, target: target } }, [
72           this.renderIcon(h, menu.meta.icon),
73           h('span', [menu.meta.title])
74         ])
75       ])
76     },
77     renderSubMenu: function (h, menu, pIndex, index) {
78       const this2_ = this
79       const subItem = [h('span', { slot: 'title' }, [this.renderIcon(h, menu.meta.icon), h('span', [menu.meta.title])])]
80       const itemArr = []
81       const pIndex_ = pIndex + '_' + index
82       console.log('menu', menu)
83       if (!menu.hideChildrenInMenu) {
84         menu.children.forEach(function (item, i) {
85           itemArr.push(this2_.renderItem(h, item, pIndex_, i))
86         })
87       }
88       return h(SubMenu, { key: menu.path ? menu.path : 'submenu_' + pIndex + '_' + index }, subItem.concat(itemArr))
89     },
90     renderItem: function (h, menu, pIndex, index) {
91       if (!menu.hidden) {
92         return menu.children && !menu.hideChildrenInMenu
93           ? this.renderSubMenu(h, menu, pIndex, index)
94           : this.renderMenuItem(h, menu, pIndex, index)
95       }
96     },
97     renderMenu: function (h, menuTree) {
98       const this2_ = this
99       const menuArr = []
100       menuTree.forEach(function (menu, i) {
101         if (!menu.hidden) {
102           menuArr.push(this2_.renderItem(h, menu, '0', i))
103         }
104       })
105       return menuArr
106     },
107     onOpenChange (openKeys) {
108       const latestOpenKey = openKeys.find(key => !this.openKeys.includes(key))
109       if (!this.rootSubmenuKeys.includes(latestOpenKey)) {
110         this.openKeys = openKeys
111       } else {
112         this.openKeys = latestOpenKey ? [latestOpenKey] : []
113       }
114     },
115     updateMenu () {
116       const routes = this.$route.matched.concat()
117
118       if (routes.length >= 4 && this.$route.meta.hidden) {
119         routes.pop()
120         this.selectedKeys = [routes[2].path]
121       } else {
122         this.selectedKeys = [routes.pop().path]
123       }
124
125       const openKeys = []
126       if (this.mode === 'inline') {
127         routes.forEach(item => {
128           openKeys.push(item.path)
129         })
130       }
131
132       this.collapsed ? (this.cachedOpenKeys = openKeys) : (this.openKeys = openKeys)
133     }
134   },
135   render (h) {
136     return h(
137       Menu,
138       {
139         props: {
140           theme: this.$props.theme,
141           mode: this.$props.mode,
142           openKeys: this.openKeys,
143           selectedKeys: this.selectedKeys
144         },
145         on: {
146           openChange: this.onOpenChange,
147           select: obj => {
148             this.selectedKeys = obj.selectedKeys
149             this.$emit('select', obj)
150           }
151         }
152       },
153       this.renderMenu(h, this.menu)
154     )
155   }
156 }