vxe-pc-ui 3.16.10 → 3.16.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (102) hide show
  1. package/es/icon/{iconfont.1783944544969.ttf → iconfont.1784124324909.ttf} +0 -0
  2. package/es/icon/iconfont.1784124324909.woff +0 -0
  3. package/es/icon/iconfont.1784124324909.woff2 +0 -0
  4. package/es/icon/style.css +33 -2
  5. package/es/icon/style.min.css +1 -1
  6. package/{lib/icon/style/iconfont.1783944544969.ttf → es/iconfont.1784124324909.ttf} +0 -0
  7. package/es/iconfont.1784124324909.woff +0 -0
  8. package/es/iconfont.1784124324909.woff2 +0 -0
  9. package/es/language/en-US.js +3 -3
  10. package/es/language/hy-AM.js +3 -3
  11. package/es/language/zh-CN.js +3 -3
  12. package/es/layout-aside/src/layout-aside.js +11 -19
  13. package/es/layout-aside/style.css +1 -3
  14. package/es/layout-aside/style.min.css +1 -1
  15. package/es/menu/src/menu.js +308 -101
  16. package/es/menu/style.css +52 -4
  17. package/es/menu/style.min.css +1 -1
  18. package/es/modal/src/modal.js +2 -2
  19. package/es/style.css +1 -1
  20. package/es/style.min.css +1 -1
  21. package/es/tree-select/src/tree-select.js +1 -1
  22. package/es/ui/index.js +1 -1
  23. package/es/ui/src/log.js +1 -1
  24. package/es/vxe-icon/style.css +33 -2
  25. package/es/vxe-icon/style.min.css +1 -1
  26. package/es/vxe-layout-aside/style.css +1 -3
  27. package/es/vxe-layout-aside/style.min.css +1 -1
  28. package/es/vxe-menu/style.css +52 -4
  29. package/es/vxe-menu/style.min.css +1 -1
  30. package/lib/{iconfont.1783944544969.ttf → icon/style/iconfont.1784124324909.ttf} +0 -0
  31. package/lib/icon/style/iconfont.1784124324909.woff +0 -0
  32. package/lib/icon/style/iconfont.1784124324909.woff2 +0 -0
  33. package/lib/icon/style/style.css +33 -2
  34. package/lib/icon/style/style.min.css +33 -2
  35. package/{es/iconfont.1783944544969.ttf → lib/iconfont.1784124324909.ttf} +0 -0
  36. package/lib/iconfont.1784124324909.woff +0 -0
  37. package/lib/iconfont.1784124324909.woff2 +0 -0
  38. package/lib/index.umd.js +314 -121
  39. package/lib/index.umd.min.js +1 -1
  40. package/lib/language/en-US.js +3 -3
  41. package/lib/language/en-US.min.js +1 -1
  42. package/lib/language/en-US.umd.js +3 -3
  43. package/lib/language/hy-AM.js +3 -3
  44. package/lib/language/hy-AM.min.js +1 -1
  45. package/lib/language/hy-AM.umd.js +3 -3
  46. package/lib/language/zh-CN.js +3 -3
  47. package/lib/language/zh-CN.min.js +1 -1
  48. package/lib/language/zh-CN.umd.js +3 -3
  49. package/lib/layout-aside/src/layout-aside.js +12 -18
  50. package/lib/layout-aside/src/layout-aside.min.js +1 -1
  51. package/lib/layout-aside/style/style.css +1 -3
  52. package/lib/layout-aside/style/style.min.css +1 -1
  53. package/lib/menu/src/menu.js +292 -93
  54. package/lib/menu/src/menu.min.js +1 -1
  55. package/lib/menu/style/style.css +52 -4
  56. package/lib/menu/style/style.min.css +1 -1
  57. package/lib/modal/src/modal.js +2 -2
  58. package/lib/modal/src/modal.min.js +1 -1
  59. package/lib/style.css +1 -1
  60. package/lib/style.min.css +1 -1
  61. package/lib/tree-select/src/tree-select.js +1 -1
  62. package/lib/tree-select/src/tree-select.min.js +1 -1
  63. package/lib/ui/index.js +1 -1
  64. package/lib/ui/index.min.js +1 -1
  65. package/lib/ui/src/log.js +1 -1
  66. package/lib/ui/src/log.min.js +1 -1
  67. package/lib/vxe-icon/style/style.css +33 -2
  68. package/lib/vxe-icon/style/style.min.css +1 -1
  69. package/lib/vxe-layout-aside/style/style.css +1 -3
  70. package/lib/vxe-layout-aside/style/style.min.css +1 -1
  71. package/lib/vxe-menu/style/style.css +52 -4
  72. package/lib/vxe-menu/style/style.min.css +1 -1
  73. package/package.json +2 -2
  74. package/packages/language/en-US.ts +3 -3
  75. package/packages/language/hy-AM.ts +3 -3
  76. package/packages/language/zh-CN.ts +3 -3
  77. package/packages/layout-aside/src/layout-aside.ts +13 -20
  78. package/packages/menu/src/menu.ts +323 -111
  79. package/packages/modal/src/modal.ts +2 -2
  80. package/packages/tree-select/src/tree-select.ts +1 -1
  81. package/styles/components/icon.scss +33 -4
  82. package/styles/components/layout-aside.scss +1 -3
  83. package/styles/components/menu.scss +64 -1
  84. package/styles/icon/iconfont.ttf +0 -0
  85. package/styles/icon/iconfont.woff +0 -0
  86. package/styles/icon/iconfont.woff2 +0 -0
  87. package/styles/theme/dark.scss +1 -0
  88. package/styles/theme/light.scss +1 -0
  89. package/styles/variable.scss +2 -1
  90. package/types/components/icon.d.ts +1 -1
  91. package/types/components/layout-aside.d.ts +3 -1
  92. package/types/components/menu.d.ts +65 -12
  93. package/types/components/table.d.ts +13 -11
  94. package/types/components/toolbar.d.ts +1 -1
  95. package/es/icon/iconfont.1783944544969.woff +0 -0
  96. package/es/icon/iconfont.1783944544969.woff2 +0 -0
  97. package/es/iconfont.1783944544969.woff +0 -0
  98. package/es/iconfont.1783944544969.woff2 +0 -0
  99. package/lib/icon/style/iconfont.1783944544969.woff +0 -0
  100. package/lib/icon/style/iconfont.1783944544969.woff2 +0 -0
  101. package/lib/iconfont.1783944544969.woff +0 -0
  102. package/lib/iconfont.1783944544969.woff2 +0 -0
@@ -2,7 +2,7 @@ import { PropType, CreateElement, VNode } from 'vue'
2
2
  import { defineVxeComponent } from '../../ui/src/comp'
3
3
  import XEUtils from 'xe-utils'
4
4
  import { VxeUI, createEvent, permission, globalMixins, globalEvents, renderEmptyElement } from '../../ui'
5
- import { toCssUnit } from '../../ui/src/dom'
5
+ import { scrollToView, toCssUnit } from '../../ui/src/dom'
6
6
  import { getLastZIndex, nextZIndex, isEnableConf } from '../../ui/src/utils'
7
7
  import { getSlotVNs } from '../../ui/src/vn'
8
8
  import { createComponentLog } from '../../ui/src/log'
@@ -16,6 +16,10 @@ const { menus, getConfig, getIcon } = VxeUI
16
16
 
17
17
  function createInternalData (): MenuInternalData {
18
18
  return {
19
+ lastActiveTime: 0,
20
+ menuInitMaps: {},
21
+ menuCacheMaps: {},
22
+ menuKeyMaps: {},
19
23
  menuEffectMaps: {}
20
24
  }
21
25
  }
@@ -43,10 +47,19 @@ export default /* define-vxe-component start */ defineVxeComponent({
43
47
  props: {
44
48
  value: [String, Number] as PropType<VxeMenuPropTypes.ModelValue>,
45
49
  expandAll: Boolean as PropType<VxeMenuPropTypes.ExpandAll>,
50
+ expandKeys: Array as PropType<VxeMenuPropTypes.ExpandKeys>,
46
51
  accordion: {
47
52
  type: Boolean as PropType<VxeMenuPropTypes.Accordion>,
48
53
  default: () => getConfig().menu.accordion
49
54
  },
55
+ border: {
56
+ type: [Boolean, String] as PropType<VxeMenuPropTypes.Border>,
57
+ default: () => getConfig().menu.border
58
+ },
59
+ optionProps: {
60
+ type: Object as PropType<VxeMenuPropTypes.OptionProps>,
61
+ default: () => getConfig().menu.optionProps
62
+ },
50
63
  collapsed: {
51
64
  type: Boolean as PropType<VxeMenuPropTypes.Collapsed>,
52
65
  default: null
@@ -84,6 +97,52 @@ export default /* define-vxe-component start */ defineVxeComponent({
84
97
  computeSize(): VxeComponentSizeType
85
98
  $xeLayoutAside(): VxeLayoutAsideConstructor | null
86
99
  }),
100
+ computePropsOpts () {
101
+ const $xeMenu = this
102
+ const props = $xeMenu
103
+
104
+ return Object.assign({}, getConfig().menu.optionProps, props.optionProps)
105
+ },
106
+ computeTitleField () {
107
+ const $xeMenu = this
108
+
109
+ const propsOpts = $xeMenu.computePropsOpts as VxeMenuPropTypes.OptionProps
110
+ return propsOpts.title || 'title'
111
+ },
112
+ computeKeyField () {
113
+ const $xeMenu = this
114
+
115
+ const propsOpts = $xeMenu.computePropsOpts as VxeMenuPropTypes.OptionProps
116
+ return propsOpts.name || 'name'
117
+ },
118
+ computeChildrenField () {
119
+ const $xeMenu = this
120
+
121
+ const propsOpts = $xeMenu.computePropsOpts as VxeMenuPropTypes.OptionProps
122
+ return propsOpts.children || 'children'
123
+ },
124
+ computeLinkUrlField () {
125
+ const $xeMenu = this
126
+
127
+ const propsOpts = $xeMenu.computePropsOpts as VxeMenuPropTypes.OptionProps
128
+ return propsOpts.linkUrl || 'href'
129
+ },
130
+ computeRouterLinkField () {
131
+ const $xeMenu = this
132
+
133
+ const propsOpts = $xeMenu.computePropsOpts as VxeMenuPropTypes.OptionProps
134
+ return propsOpts.routerLink || 'routerLink'
135
+ },
136
+ computeCurrBorder () {
137
+ const $xeMenu = this
138
+ const props = $xeMenu
139
+
140
+ const { border } = props
141
+ if (border) {
142
+ return border === true ? 'first-group' : border
143
+ }
144
+ return ''
145
+ },
87
146
  computeMenuOpts () {
88
147
  const $xeMenu = this
89
148
  const props = $xeMenu
@@ -102,15 +161,15 @@ export default /* define-vxe-component start */ defineVxeComponent({
102
161
  }
103
162
  return false
104
163
  },
105
- computeCollapseWidth () {
164
+ computeVarStyle () {
106
165
  const $xeMenu = this
107
166
  const $xeLayoutAside = $xeMenu.$xeLayoutAside
108
167
 
109
- let collapseWidth: VxeLayoutAsidePropTypes.CollapseWidth = ''
110
168
  if ($xeLayoutAside) {
111
- collapseWidth = $xeLayoutAside.collapseWidth || ''
169
+ const asideVarStyle = $xeLayoutAside.computeVarStyle
170
+ return asideVarStyle
112
171
  }
113
- return collapseWidth
172
+ return {}
114
173
  },
115
174
  computeCollapseEnterWidth () {
116
175
  const $xeMenu = this
@@ -158,6 +217,82 @@ export default /* define-vxe-component start */ defineVxeComponent({
158
217
  }
159
218
  return []
160
219
  },
220
+ setExpandByMenuKey (menuKeys: string | number | (string | number)[], expanded: boolean) {
221
+ const $xeMenu = this
222
+ const internalData = $xeMenu.internalData
223
+
224
+ const { menuKeyMaps, menuInitMaps } = internalData
225
+ if (menuKeys) {
226
+ if (!XEUtils.isArray(menuKeys)) {
227
+ menuKeys = [menuKeys]
228
+ }
229
+ menuKeys.forEach((mKey) => {
230
+ const menuItem = menuKeyMaps[mKey]
231
+ if (menuItem) {
232
+ if (expanded) {
233
+ menuInitMaps[menuItem.itemId] = true
234
+ }
235
+ menuItem.isExpand = !!expanded
236
+ }
237
+ })
238
+ }
239
+ return $xeMenu.$nextTick()
240
+ },
241
+ clearAllExpandMenu () {
242
+ const $xeMenu = this
243
+ const reactData = $xeMenu.reactData
244
+ const internalData = $xeMenu.internalData
245
+
246
+ const { menuList } = reactData
247
+ XEUtils.eachTree(menuList, (item) => {
248
+ item.isExpand = false
249
+ }, { children: 'childList' })
250
+ internalData.menuInitMaps = {}
251
+ return $xeMenu.$nextTick()
252
+ },
253
+ handleScrollToView (itemId: number) {
254
+ const $xeMenu = this
255
+
256
+ const el = $xeMenu.$refs.refElem as HTMLDivElement
257
+ const nemuEl = el ? el.querySelector<HTMLDivElement>(`.vxe-menu--item-wrapper[data-menu-id="${itemId}"]`) : null
258
+ if (nemuEl) {
259
+ scrollToView(nemuEl)
260
+ return true
261
+ }
262
+ return false
263
+ },
264
+ scrollToMenuKey (menuKey: string | number) {
265
+ const $xeMenu = this
266
+ const internalData = $xeMenu.internalData
267
+
268
+ const { menuKeyMaps } = internalData
269
+ const menuItem = menuKeyMaps[menuKey]
270
+ if (!menuItem) {
271
+ return $xeMenu.$nextTick()
272
+ }
273
+ const { itemId } = menuItem
274
+ if ($xeMenu.handleScrollToView(itemId)) {
275
+ return $xeMenu.$nextTick()
276
+ }
277
+ return $xeMenu.$nextTick().then(() => {
278
+ $xeMenu.handleScrollToView(itemId)
279
+ })
280
+ },
281
+ scrollToActiveMenu () {
282
+ const $xeMenu = this
283
+ const reactData = $xeMenu.reactData
284
+
285
+ const { activeName } = reactData
286
+ if (activeName) {
287
+ return $xeMenu.scrollToMenuKey(activeName)
288
+ }
289
+ return $xeMenu.$nextTick().then(() => {
290
+ const { activeName } = reactData
291
+ if (activeName) {
292
+ return $xeMenu.scrollToMenuKey(activeName)
293
+ }
294
+ })
295
+ },
161
296
  getMenuTitle (item: VxeMenuPropTypes.MenuOption) {
162
297
  return `${item.title || item.name}`
163
298
  },
@@ -172,14 +307,17 @@ export default /* define-vxe-component start */ defineVxeComponent({
172
307
  updateActiveMenu (isDefExpand?: boolean) {
173
308
  const $xeMenu = this
174
309
  const reactData = $xeMenu.reactData
310
+ const internalData = $xeMenu.internalData
175
311
 
176
312
  const { activeName } = reactData
313
+ const { menuInitMaps } = internalData
177
314
  XEUtils.eachTree(reactData.menuList, (item, index, items, path, parent, nodes) => {
178
315
  if (item.itemKey === activeName) {
179
316
  nodes.forEach(obj => {
180
317
  obj.isActive = true
181
318
  if (isDefExpand) {
182
319
  obj.isExpand = true
320
+ menuInitMaps[obj.itemId] = true
183
321
  }
184
322
  })
185
323
  item.isExactActive = true
@@ -193,22 +331,63 @@ export default /* define-vxe-component start */ defineVxeComponent({
193
331
  const $xeMenu = this
194
332
  const props = $xeMenu
195
333
  const reactData = $xeMenu.reactData
334
+ const internalData = $xeMenu.internalData
196
335
 
197
- const { options, expandAll } = props
198
- reactData.menuList = XEUtils.mapTree(options, (item, index, items, path, parent) => {
199
- const objItem = {
200
- ...item,
201
- parentKey: parent ? (parent.name || path.slice(0, path.length - 1).join(',')) : '',
336
+ const { options, expandAll, expandKeys } = props
337
+ const muInitMaps: Record<string, boolean> = {}
338
+ const titleField = $xeMenu.computeTitleField
339
+ const keyField = $xeMenu.computeKeyField
340
+ const childrenField = $xeMenu.computeChildrenField
341
+ const linkUrlField = $xeMenu.computeLinkUrlField
342
+ const routerLinkField = $xeMenu.computeRouterLinkField
343
+ const defaultExpandMaps: Record<string, boolean> = {}
344
+ if (expandKeys) {
345
+ expandKeys.forEach(key => {
346
+ defaultExpandMaps[key] = true
347
+ })
348
+ }
349
+ const muCacheMaps: Record<string, VxeMenuDefines.MenuItem> = {}
350
+ const muKeyMaps: Record<string, VxeMenuDefines.MenuItem> = {}
351
+ reactData.menuList = XEUtils.mapTree(options, (item, index, items, path, parentItem) => {
352
+ const itemId = ++nemuUniqueKey
353
+ const itemKey = item[keyField] || path.join(',')
354
+ const childList = item[childrenField]
355
+ const hasChild = childList && childList.length > 0
356
+ const isExpand = hasChild ? (XEUtils.isBoolean(item.expanded) ? item.expanded : (defaultExpandMaps[itemKey] || !!expandAll)) : false
357
+ if (isExpand) {
358
+ muInitMaps[itemId] = true
359
+ }
360
+ const objItem: VxeMenuDefines.MenuItem = {
361
+ itemConf: item,
362
+ title: item[titleField],
363
+ name: item[keyField],
364
+ icon: item.icon,
365
+ linkUrl: item[linkUrlField],
366
+ linkTarget: item.linkTarget,
367
+ routerLink: item[routerLinkField],
368
+ permissionCode: item.permissionCode,
369
+ children: childList,
370
+ slots: item.slots,
371
+ parentKey: parentItem ? (parentItem.name || path.slice(0, path.length - 1).join(',')) : '',
202
372
  level: path.length,
203
- itemId: ++nemuUniqueKey,
204
- itemKey: item.name || path.join(','),
373
+ itemId,
374
+ itemKey,
205
375
  isExactActive: false,
206
376
  isActive: false,
207
- isExpand: XEUtils.isBoolean(item.expanded) ? item.expanded : !!expandAll,
208
- hasChild: item.children && item.children.length > 0
209
- } as VxeMenuDefines.MenuItem
377
+ isExpand,
378
+ hasChild,
379
+ childList: []
380
+ }
381
+ if (muKeyMaps[itemKey]) {
382
+ errLog('vxe.error.repeatKey', [keyField, item[keyField]])
383
+ }
384
+ muCacheMaps[itemId] = objItem
385
+ muKeyMaps[itemKey] = objItem
210
386
  return objItem
211
387
  }, { children: 'children', mapChildren: 'childList' })
388
+ internalData.menuInitMaps = muInitMaps
389
+ internalData.menuCacheMaps = muCacheMaps
390
+ internalData.menuKeyMaps = muKeyMaps
212
391
  },
213
392
  updateCollapseStyle () {
214
393
  const $xeMenu = this
@@ -218,10 +397,7 @@ export default /* define-vxe-component start */ defineVxeComponent({
218
397
  const { collapseFixed } = props
219
398
  if (collapseFixed) {
220
399
  $xeMenu.$nextTick(() => {
221
- const { isEnterCollapse } = reactData
222
400
  const isCollapsed = $xeMenu.computeIsCollapsed
223
- const collapseEnterWidth = $xeMenu.computeCollapseEnterWidth
224
- const collapseWidth = $xeMenu.computeCollapseWidth
225
401
  const el = $xeMenu.$refs.refElem as HTMLDivElement
226
402
  if (el) {
227
403
  const clientRect = el.getBoundingClientRect()
@@ -231,7 +407,6 @@ export default /* define-vxe-component start */ defineVxeComponent({
231
407
  top: toCssUnit(clientRect.top),
232
408
  left: toCssUnit(clientRect.left),
233
409
  height: toCssUnit(parentNode.clientHeight),
234
- width: isEnterCollapse ? (collapseEnterWidth ? toCssUnit(collapseEnterWidth) : '') : (collapseWidth ? toCssUnit(collapseWidth) : ''),
235
410
  zIndex: reactData.collapseZindex
236
411
  }
237
412
  : {}
@@ -270,7 +445,7 @@ export default /* define-vxe-component start */ defineVxeComponent({
270
445
  const internalData = $xeMenu.internalData
271
446
 
272
447
  const { accordion } = props
273
- const { menuEffectMaps } = internalData
448
+ const { menuEffectMaps, menuInitMaps } = internalData
274
449
  const { itemId, hasChild, isExpand } = item
275
450
  const isCollapsed = $xeMenu.computeIsCollapsed
276
451
  const expanded = !isExpand
@@ -290,6 +465,7 @@ export default /* define-vxe-component start */ defineVxeComponent({
290
465
  })
291
466
  }
292
467
  item.isExpand = expanded
468
+ menuInitMaps[itemId] = true
293
469
 
294
470
  const wrapperEl = isCollapsed ? $xeMenu.$refs.refCollapseElem as HTMLDivElement : $xeMenu.$refs.refElem as HTMLDivElement
295
471
  if (wrapperEl) {
@@ -326,7 +502,7 @@ export default /* define-vxe-component start */ defineVxeComponent({
326
502
  const menuOpts = $xeMenu.computeMenuOpts
327
503
  if (menuConfig ? isEnableConf(menuOpts) : menuOpts.enabled) {
328
504
  const { options, visibleMethod } = menuOpts
329
- if (!visibleMethod || visibleMethod({ $menu: $xeMenu, options, currentMenu: item })) {
505
+ if (!visibleMethod || visibleMethod({ $menu: $xeMenu, options, currentMenu: item, currentOption: item.itemConf })) {
330
506
  if (VxeUI.contextMenu) {
331
507
  VxeUI.contextMenu.openByEvent(evnt, {
332
508
  options,
@@ -335,7 +511,7 @@ export default /* define-vxe-component start */ defineVxeComponent({
335
511
  const { option } = eventParams
336
512
  const gMenuOpts = menus.get(option.code)
337
513
  const mmMethod = gMenuOpts ? gMenuOpts.menuMenuMethod : null
338
- const params = { menu: option, currentMenu: item, $event: evnt, $menu: $xeMenu }
514
+ const params = { menu: option, currentMenu: item, currentOption: item.itemConf, $event: evnt, $menu: $xeMenu }
339
515
  if (mmMethod) {
340
516
  mmMethod(params, evnt)
341
517
  }
@@ -350,19 +526,27 @@ export default /* define-vxe-component start */ defineVxeComponent({
350
526
  },
351
527
  handleClickMenu (evnt: MouseEvent, item: VxeMenuDefines.MenuItem, itemList: VxeMenuDefines.MenuItem[]) {
352
528
  const $xeMenu = this
529
+ const reactData = $xeMenu.reactData
530
+ const internalData = $xeMenu.internalData
353
531
 
354
- const { itemKey, routerLink, hasChild } = item
355
- if (routerLink) {
532
+ const { itemKey, linkUrl, routerLink, hasChild } = item
533
+ if (linkUrl || routerLink) {
356
534
  $xeMenu.emitModel(itemKey)
535
+ reactData.isEnterCollapse = false
536
+ internalData.lastActiveTime = Date.now()
357
537
  } else {
358
538
  if (hasChild) {
359
539
  $xeMenu.handleClickIconCollapse(evnt, item, itemList)
360
540
  } else {
361
541
  $xeMenu.emitModel(itemKey)
542
+ reactData.isEnterCollapse = false
543
+ internalData.lastActiveTime = Date.now()
362
544
  }
363
545
  }
364
546
  const params = {
365
547
  currentMenu: item,
548
+ currentOption: item.itemConf,
549
+ option: item.itemConf,
366
550
 
367
551
  // 已废弃
368
552
  menu: item
@@ -372,32 +556,18 @@ export default /* define-vxe-component start */ defineVxeComponent({
372
556
  handleMenuMouseenter () {
373
557
  const $xeMenu = this
374
558
  const reactData = $xeMenu.reactData
559
+ const internalData = $xeMenu.internalData
375
560
 
376
- const { collapseStyle } = reactData
377
- const collapseEnterWidth = $xeMenu.computeCollapseEnterWidth
378
- reactData.collapseStyle = Object.assign({}, collapseStyle, {
379
- width: collapseEnterWidth ? toCssUnit(collapseEnterWidth) : ''
380
- })
381
- reactData.isEnterCollapse = true
382
- },
383
- handleMenuMouseover () {
384
- const $xeMenu = this
385
- const reactData = $xeMenu.reactData
561
+ const { lastActiveTime } = internalData
386
562
 
387
- const { isEnterCollapse } = reactData
388
- if (!isEnterCollapse) {
389
- $xeMenu.handleMenuMouseenter()
563
+ if (lastActiveTime < Date.now() - 500) {
564
+ reactData.isEnterCollapse = true
390
565
  }
391
566
  },
392
567
  handleMenuMouseleave () {
393
568
  const $xeMenu = this
394
569
  const reactData = $xeMenu.reactData
395
570
 
396
- const { collapseStyle } = reactData
397
- const el = $xeMenu.$refs.refElem as HTMLDivElement
398
- reactData.collapseStyle = Object.assign({}, collapseStyle, {
399
- width: el ? toCssUnit(el.offsetWidth) : ''
400
- })
401
571
  reactData.isEnterCollapse = false
402
572
  },
403
573
 
@@ -417,11 +587,10 @@ export default /* define-vxe-component start */ defineVxeComponent({
417
587
  const title = $xeMenu.getMenuTitle(item)
418
588
  const isCollapsed = $xeMenu.computeIsCollapsed
419
589
  const params = {
420
- currentMenu: item as Required<VxeMenuDefines.MenuItem>,
421
- collapsed: isCollapsed,
422
-
423
- // 已废弃
424
- option: item as Required<VxeMenuDefines.MenuItem>
590
+ currentMenu: item,
591
+ currentOption: item.itemConf,
592
+ option: item.itemConf,
593
+ collapsed: isCollapsed
425
594
  }
426
595
  return [
427
596
  optionSlot
@@ -464,72 +633,91 @@ export default /* define-vxe-component start */ defineVxeComponent({
464
633
  renderDefaultChildren (h: CreateElement, item: VxeMenuDefines.MenuItem, itemList: VxeMenuDefines.MenuItem[]): VNode {
465
634
  const $xeMenu = this
466
635
  const reactData = $xeMenu.reactData
636
+ const internalData = $xeMenu.internalData
467
637
 
468
- const { itemId, itemKey, level, hasChild, isActive, isExactActive, isExpand, routerLink, childList } = item
638
+ const { itemId, itemKey, level, hasChild, isActive, isExactActive, isExpand, linkUrl, routerLink, linkTarget, childList } = item
469
639
  const { isEnterCollapse } = reactData
640
+ const { menuInitMaps } = internalData
470
641
  const isCollapsed = $xeMenu.computeIsCollapsed
471
642
  if (item.permissionCode) {
472
643
  if (!permission.checkVisible(item.permissionCode)) {
473
644
  return renderEmptyElement($xeMenu)
474
645
  }
475
646
  }
647
+ const isExpandChild = (!isCollapsed || isEnterCollapse) && isExpand
648
+ const linkOns = {
649
+ contextmenu (evnt: MouseEvent) {
650
+ $xeMenu.handleContextmenuEvent(evnt, item)
651
+ },
652
+ click (evnt: MouseEvent) {
653
+ $xeMenu.handleClickMenu(evnt, item, itemList)
654
+ }
655
+ }
476
656
  return h('div', {
477
657
  key: itemKey,
478
658
  class: ['vxe-menu--item-wrapper', `vxe-menu--item-level${level}`, {
659
+ 'has--child': hasChild,
479
660
  'is--exact-active': isExactActive,
480
661
  'is--active': isActive,
481
- 'is--expand': (!isCollapsed || isEnterCollapse) && isExpand
662
+ 'is--expand': isExpandChild
482
663
  }],
483
664
  attrs: {
484
665
  'data-menu-id': itemId
485
666
  }
486
667
  }, [
487
- routerLink
488
- ? h('router-link', {
489
- class: 'vxe-menu--item-link',
490
- props: {
491
- custom: true,
492
- to: routerLink
668
+ linkUrl
669
+ ? h('a', {
670
+ class: 'vxe-menu--item-link is--link',
671
+ attrs: {
672
+ href: linkUrl,
673
+ target: linkTarget
493
674
  },
494
- on: {
495
- contextmenu (evnt: MouseEvent) {
496
- $xeMenu.handleContextmenuEvent(evnt, item)
497
- },
498
- click (evnt: MouseEvent) {
499
- $xeMenu.handleClickMenu(evnt, item, itemList)
500
- }
501
- }
675
+ on: linkOns
502
676
  }, $xeMenu.renderMenuTitle(h, item, itemList))
503
- : h('div', {
504
- class: 'vxe-menu--item-link',
505
- on: {
506
- contextmenu (evnt: MouseEvent) {
507
- $xeMenu.handleContextmenuEvent(evnt, item)
508
- },
509
- click (evnt: MouseEvent) {
510
- $xeMenu.handleClickMenu(evnt, item, itemList)
511
- }
512
- }
513
- }, $xeMenu.renderMenuTitle(h, item, itemList)),
677
+ : (
678
+ routerLink
679
+ ? h('router-link', {
680
+ class: 'vxe-menu--item-link is--router',
681
+ props: {
682
+ custom: true,
683
+ to: routerLink,
684
+ target: linkTarget
685
+ },
686
+ on: linkOns
687
+ }, $xeMenu.renderMenuTitle(h, item, itemList))
688
+ : h('div', {
689
+ class: 'vxe-menu--item-link is--default',
690
+ on: linkOns
691
+ }, $xeMenu.renderMenuTitle(h, item, itemList))
692
+ ),
514
693
  hasChild
515
694
  ? h('div', {
516
695
  class: 'vxe-menu--item-group'
517
- }, childList.map(child => $xeMenu.renderDefaultChildren(h, child, childList)))
696
+ }, isExpandChild || menuInitMaps[itemId] ? childList.map(child => $xeMenu.renderDefaultChildren(h, child, childList)) : [])
518
697
  : renderEmptyElement($xeMenu)
519
698
  ])
520
699
  },
521
700
  renderCollapseChildren (h: CreateElement, item: VxeMenuDefines.MenuItem, itemList: VxeMenuDefines.MenuItem[]): VNode {
522
701
  const $xeMenu = this
523
702
 
524
- const { itemId, itemKey, level, hasChild, isActive, isExactActive, routerLink, childList } = item
703
+ const { itemId, itemKey, level, hasChild, isActive, isExactActive, routerLink, linkUrl, linkTarget, childList } = item
525
704
  if (item.permissionCode) {
526
705
  if (!permission.checkVisible(item.permissionCode)) {
527
706
  return renderEmptyElement($xeMenu)
528
707
  }
529
708
  }
709
+ const linkOns = {
710
+ contextmenu (evnt: MouseEvent) {
711
+ $xeMenu.handleContextmenuEvent(evnt, item)
712
+ },
713
+ click (evnt: MouseEvent) {
714
+ $xeMenu.handleClickMenu(evnt, item, itemList)
715
+ }
716
+ }
530
717
  return h('div', {
531
718
  key: itemKey,
532
719
  class: ['vxe-menu--item-wrapper', `vxe-menu--item-level${level}`, {
720
+ 'has--child': hasChild,
533
721
  'is--exact-active': isExactActive,
534
722
  'is--active': isActive
535
723
  }],
@@ -537,33 +725,31 @@ export default /* define-vxe-component start */ defineVxeComponent({
537
725
  'data-menu-id': itemId
538
726
  }
539
727
  }, [
540
- routerLink
541
- ? h('router-link', {
542
- class: 'vxe-menu--item-link',
543
- props: {
544
- custom: true,
545
- to: routerLink
728
+ linkUrl
729
+ ? h('a', {
730
+ class: 'vxe-menu--item-link is--link',
731
+ attrs: {
732
+ href: linkUrl,
733
+ target: linkTarget
546
734
  },
547
- on: {
548
- contextmenu (evnt: MouseEvent) {
549
- $xeMenu.handleContextmenuEvent(evnt, item)
550
- },
551
- click (evnt: MouseEvent) {
552
- $xeMenu.handleClickMenu(evnt, item, itemList)
553
- }
554
- }
735
+ on: linkOns
555
736
  }, $xeMenu.renderMenuTitle(h, item, itemList))
556
- : h('div', {
557
- class: 'vxe-menu--item-link',
558
- on: {
559
- contextmenu (evnt: MouseEvent) {
560
- $xeMenu.handleContextmenuEvent(evnt, item)
561
- },
562
- click (evnt: MouseEvent) {
563
- $xeMenu.handleClickMenu(evnt, item, itemList)
564
- }
565
- }
566
- }, $xeMenu.renderMenuTitle(h, item, itemList)),
737
+ : (
738
+ routerLink
739
+ ? h('router-link', {
740
+ class: 'vxe-menu--item-link is--router',
741
+ props: {
742
+ custom: true,
743
+ to: routerLink,
744
+ target: linkTarget
745
+ },
746
+ on: linkOns
747
+ }, $xeMenu.renderMenuTitle(h, item, itemList))
748
+ : h('div', {
749
+ class: 'vxe-menu--item-link is--default',
750
+ on: linkOns
751
+ }, $xeMenu.renderMenuTitle(h, item, itemList))
752
+ ),
567
753
  hasChild
568
754
  ? h('div', {
569
755
  class: 'vxe-menu--item-group'
@@ -574,31 +760,47 @@ export default /* define-vxe-component start */ defineVxeComponent({
574
760
  renderVN (h: CreateElement): VNode {
575
761
  const $xeMenu = this
576
762
  const props = $xeMenu
763
+ const slots = $xeMenu.$scopedSlots
577
764
  const reactData = $xeMenu.reactData
578
765
 
579
766
  const { loading, collapseFixed } = props
580
767
  const { initialized, menuList, collapseStyle, isEnterCollapse } = reactData
581
768
  const vSize = $xeMenu.computeSize
582
769
  const isCollapsed = $xeMenu.computeIsCollapsed
770
+ const currBorder = $xeMenu.computeCurrBorder
771
+ const varStyle = $xeMenu.computeVarStyle
772
+ const headerSlot = slots.header
773
+ const footerSlot = slots.footer
583
774
  let ons: Record<string, any> = {}
584
775
  if (collapseFixed) {
585
776
  ons = {
586
777
  mouseenter: $xeMenu.handleMenuMouseenter,
587
- mouseover: $xeMenu.handleMenuMouseover,
588
778
  mouseleave: $xeMenu.handleMenuMouseleave
589
779
  }
590
780
  }
781
+ const stParams = { collapsed: isCollapsed }
591
782
  return h('div', {
592
783
  ref: 'refElem',
593
784
  class: ['vxe-menu', {
785
+ [`border--${currBorder}`]: currBorder,
594
786
  [`size--${vSize}`]: vSize,
595
787
  'is--collapsed': isCollapsed,
596
788
  'is--loading': loading
597
789
  }]
598
790
  }, [
791
+ headerSlot
792
+ ? h('div', {
793
+ class: 'vxe-menu--header'
794
+ }, headerSlot(stParams))
795
+ : renderEmptyElement($xeMenu),
599
796
  h('div', {
600
- class: 'vxe-menu--item-list'
797
+ class: 'vxe-menu--body'
601
798
  }, menuList.map(child => isCollapsed ? $xeMenu.renderCollapseChildren(h, child, menuList) : $xeMenu.renderDefaultChildren(h, child, menuList))),
799
+ footerSlot
800
+ ? h('div', {
801
+ class: 'vxe-menu--footer'
802
+ }, footerSlot(stParams))
803
+ : renderEmptyElement($xeMenu),
602
804
  initialized
603
805
  ? h('div', {
604
806
  ref: 'refCollapseElem',
@@ -608,15 +810,25 @@ export default /* define-vxe-component start */ defineVxeComponent({
608
810
  'is--enter': isEnterCollapse,
609
811
  'is--loading': loading
610
812
  }],
611
- style: collapseStyle,
813
+ style: Object.assign({}, varStyle, collapseStyle),
612
814
  on: ons
613
- }, [
614
- isCollapsed
615
- ? h('div', {
616
- class: 'vxe-menu--item-list'
617
- }, menuList.map(child => $xeMenu.renderDefaultChildren(h, child, menuList)))
618
- : renderEmptyElement($xeMenu)
619
- ])
815
+ }, isCollapsed
816
+ ? [
817
+ headerSlot
818
+ ? h('div', {
819
+ class: 'vxe-menu--header'
820
+ }, headerSlot(stParams))
821
+ : renderEmptyElement($xeMenu),
822
+ h('div', {
823
+ class: 'vxe-menu--body'
824
+ }, menuList.map(child => $xeMenu.renderDefaultChildren(h, child, menuList))),
825
+ footerSlot
826
+ ? h('div', {
827
+ class: 'vxe-menu--footer'
828
+ }, footerSlot(stParams))
829
+ : renderEmptyElement($xeMenu)
830
+ ]
831
+ : [])
620
832
  : renderEmptyElement($xeMenu),
621
833
  /**
622
834
  * 加载中