vxe-pc-ui 4.16.10 → 4.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 (101) hide show
  1. package/dist/all.esm.js +282 -145
  2. package/dist/style.css +1 -1
  3. package/dist/style.min.css +1 -1
  4. package/es/icon/{iconfont.1783944746257.ttf → iconfont.1784124328754.ttf} +0 -0
  5. package/es/icon/iconfont.1784124328754.woff +0 -0
  6. package/es/icon/iconfont.1784124328754.woff2 +0 -0
  7. package/es/icon/style.css +33 -2
  8. package/es/icon/style.min.css +1 -1
  9. package/{lib/icon/style/iconfont.1783944746257.ttf → es/iconfont.1784124328754.ttf} +0 -0
  10. package/es/iconfont.1784124328754.woff +0 -0
  11. package/es/iconfont.1784124328754.woff2 +0 -0
  12. package/es/language/en-US.js +3 -3
  13. package/es/language/hy-AM.js +3 -3
  14. package/es/language/zh-CN.js +3 -3
  15. package/es/layout-aside/src/layout-aside.js +13 -20
  16. package/es/layout-aside/style.css +1 -3
  17. package/es/layout-aside/style.min.css +1 -1
  18. package/es/menu/src/menu.js +265 -121
  19. package/es/menu/style.css +51 -3
  20. package/es/menu/style.min.css +1 -1
  21. package/es/style.css +1 -1
  22. package/es/style.min.css +1 -1
  23. package/es/tree-select/src/tree-select.js +1 -1
  24. package/es/ui/index.js +1 -1
  25. package/es/ui/src/log.js +1 -1
  26. package/es/vxe-icon/style.css +33 -2
  27. package/es/vxe-icon/style.min.css +1 -1
  28. package/es/vxe-layout-aside/style.css +1 -3
  29. package/es/vxe-layout-aside/style.min.css +1 -1
  30. package/es/vxe-menu/style.css +51 -3
  31. package/es/vxe-menu/style.min.css +1 -1
  32. package/lib/{iconfont.1783944746257.ttf → icon/style/iconfont.1784124328754.ttf} +0 -0
  33. package/lib/icon/style/iconfont.1784124328754.woff +0 -0
  34. package/lib/icon/style/iconfont.1784124328754.woff2 +0 -0
  35. package/lib/icon/style/style.css +33 -2
  36. package/lib/icon/style/style.min.css +33 -2
  37. package/{es/iconfont.1783944746257.ttf → lib/iconfont.1784124328754.ttf} +0 -0
  38. package/lib/iconfont.1784124328754.woff +0 -0
  39. package/lib/iconfont.1784124328754.woff2 +0 -0
  40. package/lib/index.umd.js +300 -134
  41. package/lib/index.umd.min.js +1 -1
  42. package/lib/language/en-US.js +3 -3
  43. package/lib/language/en-US.min.js +1 -1
  44. package/lib/language/en-US.umd.js +3 -3
  45. package/lib/language/hy-AM.js +3 -3
  46. package/lib/language/hy-AM.min.js +1 -1
  47. package/lib/language/hy-AM.umd.js +3 -3
  48. package/lib/language/zh-CN.js +3 -3
  49. package/lib/language/zh-CN.min.js +1 -1
  50. package/lib/language/zh-CN.umd.js +3 -3
  51. package/lib/layout-aside/src/layout-aside.js +12 -18
  52. package/lib/layout-aside/src/layout-aside.min.js +1 -1
  53. package/lib/layout-aside/style/style.css +1 -3
  54. package/lib/layout-aside/style/style.min.css +1 -1
  55. package/lib/menu/src/menu.js +283 -116
  56. package/lib/menu/src/menu.min.js +1 -1
  57. package/lib/menu/style/style.css +51 -3
  58. package/lib/menu/style/style.min.css +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 +51 -3
  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 +15 -21
  78. package/packages/menu/src/menu.ts +302 -132
  79. package/packages/tree-select/src/tree-select.ts +1 -1
  80. package/styles/components/icon.scss +33 -4
  81. package/styles/components/layout-aside.scss +1 -3
  82. package/styles/components/menu.scss +64 -1
  83. package/styles/icon/iconfont.ttf +0 -0
  84. package/styles/icon/iconfont.woff +0 -0
  85. package/styles/icon/iconfont.woff2 +0 -0
  86. package/styles/theme/dark.scss +1 -0
  87. package/styles/theme/light.scss +1 -0
  88. package/styles/variable.scss +2 -1
  89. package/types/components/icon.d.ts +1 -1
  90. package/types/components/layout-aside.d.ts +5 -4
  91. package/types/components/menu.d.ts +66 -12
  92. package/types/components/table.d.ts +12 -11
  93. package/types/components/toolbar.d.ts +1 -1
  94. package/es/icon/iconfont.1783944746257.woff +0 -0
  95. package/es/icon/iconfont.1783944746257.woff2 +0 -0
  96. package/es/iconfont.1783944746257.woff +0 -0
  97. package/es/iconfont.1783944746257.woff2 +0 -0
  98. package/lib/icon/style/iconfont.1783944746257.woff +0 -0
  99. package/lib/icon/style/iconfont.1783944746257.woff2 +0 -0
  100. package/lib/iconfont.1783944746257.woff +0 -0
  101. package/lib/iconfont.1783944746257.woff2 +0 -0
@@ -1,8 +1,8 @@
1
- import { ref, h, reactive, inject, resolveComponent, watch, computed, nextTick, onBeforeUnmount, onMounted } from 'vue';
1
+ import { ref, h, reactive, Teleport, inject, resolveComponent, watch, computed, nextTick, onBeforeUnmount, onMounted } from 'vue';
2
2
  import { defineVxeComponent } from '../../ui/src/comp';
3
3
  import XEUtils from 'xe-utils';
4
4
  import { VxeUI, createEvent, permission, useSize, 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';
@@ -11,6 +11,10 @@ const { errLog } = createComponentLog('menu');
11
11
  const { menus, getConfig, getIcon } = VxeUI;
12
12
  function createInternalData() {
13
13
  return {
14
+ lastActiveTime: 0,
15
+ menuInitMaps: {},
16
+ menuCacheMaps: {},
17
+ menuKeyMaps: {},
14
18
  menuEffectMaps: {}
15
19
  };
16
20
  }
@@ -31,10 +35,19 @@ export default defineVxeComponent({
31
35
  props: {
32
36
  modelValue: [String, Number],
33
37
  expandAll: Boolean,
38
+ expandKeys: Array,
34
39
  accordion: {
35
40
  type: Boolean,
36
41
  default: () => getConfig().menu.accordion
37
42
  },
43
+ border: {
44
+ type: [Boolean, String],
45
+ default: () => getConfig().menu.border
46
+ },
47
+ optionProps: {
48
+ type: Object,
49
+ default: () => getConfig().menu.optionProps
50
+ },
38
51
  collapsed: {
39
52
  type: Boolean,
40
53
  default: null
@@ -72,6 +85,36 @@ export default defineVxeComponent({
72
85
  const computeMenuOpts = computed(() => {
73
86
  return Object.assign({}, getConfig().menu.menuConfig, props.menuConfig);
74
87
  });
88
+ const computePropsOpts = computed(() => {
89
+ return Object.assign({}, getConfig().menu.optionProps, props.optionProps);
90
+ });
91
+ const computeTitleField = computed(() => {
92
+ const propsOpts = computePropsOpts.value;
93
+ return propsOpts.title || 'title';
94
+ });
95
+ const computeKeyField = computed(() => {
96
+ const propsOpts = computePropsOpts.value;
97
+ return propsOpts.name || 'name';
98
+ });
99
+ const computeChildrenField = computed(() => {
100
+ const propsOpts = computePropsOpts.value;
101
+ return propsOpts.children || 'children';
102
+ });
103
+ const computeLinkUrlField = computed(() => {
104
+ const propsOpts = computePropsOpts.value;
105
+ return propsOpts.linkUrl || 'href';
106
+ });
107
+ const computeRouterLinkField = computed(() => {
108
+ const propsOpts = computePropsOpts.value;
109
+ return propsOpts.routerLink || 'routerLink';
110
+ });
111
+ const computeCurrBorder = computed(() => {
112
+ const { border } = props;
113
+ if (border) {
114
+ return border === true ? 'first-group' : border;
115
+ }
116
+ return '';
117
+ });
75
118
  const computeIsCollapsed = computed(() => {
76
119
  const { collapsed } = props;
77
120
  if (XEUtils.isBoolean(collapsed)) {
@@ -82,19 +125,13 @@ export default defineVxeComponent({
82
125
  }
83
126
  return false;
84
127
  });
85
- const computeCollapseWidth = computed(() => {
86
- let collapseWidth = '';
87
- if ($xeLayoutAside) {
88
- collapseWidth = $xeLayoutAside.props.collapseWidth || '';
89
- }
90
- return collapseWidth;
91
- });
92
- const computeCollapseEnterWidth = computed(() => {
93
- let width = '';
128
+ const computeVarStyle = computed(() => {
94
129
  if ($xeLayoutAside) {
95
- width = $xeLayoutAside.props.width || '';
130
+ const { computeVarStyle: asideComputeVarStyle } = $xeLayoutAside.getComputeMaps();
131
+ const asideVarStyle = asideComputeVarStyle.value;
132
+ return asideVarStyle;
96
133
  }
97
- return width;
134
+ return {};
98
135
  });
99
136
  const computeMaps = {
100
137
  computeSize
@@ -104,6 +141,7 @@ export default defineVxeComponent({
104
141
  props,
105
142
  context,
106
143
  reactData,
144
+ internalData,
107
145
  getRefMaps: () => refMaps,
108
146
  getComputeMaps: () => computeMaps
109
147
  };
@@ -117,12 +155,14 @@ export default defineVxeComponent({
117
155
  };
118
156
  const updateActiveMenu = (isDefExpand) => {
119
157
  const { activeName } = reactData;
120
- XEUtils.eachTree(reactData.menuList, (item, index, items, path, parent, nodes) => {
158
+ const { menuInitMaps } = internalData;
159
+ XEUtils.eachTree(reactData.menuList, (item, index, items, path, parentItem, nodes) => {
121
160
  if (item.itemKey === activeName) {
122
161
  nodes.forEach(obj => {
123
162
  obj.isActive = true;
124
163
  if (isDefExpand) {
125
164
  obj.isExpand = true;
165
+ menuInitMaps[obj.itemId] = true;
126
166
  }
127
167
  });
128
168
  item.isExactActive = true;
@@ -134,20 +174,67 @@ export default defineVxeComponent({
134
174
  }, { children: 'childList' });
135
175
  };
136
176
  const updateMenuConfig = () => {
137
- const { options, expandAll } = props;
138
- reactData.menuList = XEUtils.mapTree(options, (item, index, items, path, parent) => {
139
- const objItem = Object.assign(Object.assign({}, item), { parentKey: parent ? (parent.name || path.slice(0, path.length - 1).join(',')) : '', level: path.length, itemId: ++nemuUniqueKey, itemKey: item.name || path.join(','), isExactActive: false, isActive: false, isExpand: XEUtils.isBoolean(item.expanded) ? item.expanded : !!expandAll, hasChild: item.children && item.children.length > 0 });
177
+ const { options, expandAll, expandKeys } = props;
178
+ const muInitMaps = {};
179
+ const titleField = computeTitleField.value;
180
+ const keyField = computeKeyField.value;
181
+ const childrenField = computeChildrenField.value;
182
+ const linkUrlField = computeLinkUrlField.value;
183
+ const routerLinkField = computeRouterLinkField.value;
184
+ const defaultExpandMaps = {};
185
+ if (expandKeys) {
186
+ expandKeys.forEach(key => {
187
+ defaultExpandMaps[key] = true;
188
+ });
189
+ }
190
+ const muCacheMaps = {};
191
+ const muKeyMaps = {};
192
+ reactData.menuList = XEUtils.mapTree(options, (item, index, items, path, parentItem) => {
193
+ const itemId = ++nemuUniqueKey;
194
+ const itemKey = item[keyField] || path.join(',');
195
+ const childList = item[childrenField];
196
+ const hasChild = childList && childList.length > 0;
197
+ const isExpand = hasChild ? (XEUtils.isBoolean(item.expanded) ? item.expanded : (defaultExpandMaps[itemKey] || !!expandAll)) : false;
198
+ if (isExpand) {
199
+ muInitMaps[itemId] = true;
200
+ }
201
+ const objItem = {
202
+ itemConf: item,
203
+ title: item[titleField],
204
+ name: item[keyField],
205
+ icon: item.icon,
206
+ linkUrl: item[linkUrlField],
207
+ linkTarget: item.linkTarget,
208
+ routerLink: item[routerLinkField],
209
+ permissionCode: item.permissionCode,
210
+ children: childList,
211
+ slots: item.slots,
212
+ parentKey: parentItem ? (parentItem.name || path.slice(0, path.length - 1).join(',')) : '',
213
+ level: path.length,
214
+ itemId,
215
+ itemKey,
216
+ isExactActive: false,
217
+ isActive: false,
218
+ isExpand,
219
+ hasChild,
220
+ childList: []
221
+ };
222
+ if (muKeyMaps[itemKey]) {
223
+ errLog('vxe.error.repeatKey', [keyField, item[keyField]]);
224
+ }
225
+ muCacheMaps[itemId] = objItem;
226
+ muKeyMaps[itemKey] = objItem;
140
227
  return objItem;
141
228
  }, { children: 'children', mapChildren: 'childList' });
229
+ internalData.menuInitMaps = muInitMaps;
230
+ internalData.menuCacheMaps = muCacheMaps;
231
+ internalData.menuKeyMaps = muKeyMaps;
142
232
  };
143
233
  const updateCollapseStyle = () => {
144
234
  const { collapseFixed } = props;
145
235
  if (collapseFixed) {
146
236
  nextTick(() => {
147
- const { isEnterCollapse } = reactData;
148
237
  const isCollapsed = computeIsCollapsed.value;
149
- const collapseEnterWidth = computeCollapseEnterWidth.value;
150
- const collapseWidth = computeCollapseWidth.value;
151
238
  const el = refElem.value;
152
239
  if (el) {
153
240
  const clientRect = el.getBoundingClientRect();
@@ -157,7 +244,6 @@ export default defineVxeComponent({
157
244
  top: toCssUnit(clientRect.top),
158
245
  left: toCssUnit(clientRect.left),
159
246
  height: toCssUnit(parentNode.clientHeight),
160
- width: isEnterCollapse ? (collapseEnterWidth ? toCssUnit(collapseEnterWidth) : '') : (collapseWidth ? toCssUnit(collapseWidth) : ''),
161
247
  zIndex: reactData.collapseZindex
162
248
  }
163
249
  : {};
@@ -173,12 +259,6 @@ export default defineVxeComponent({
173
259
  if (isCollapsed) {
174
260
  if (!initialized) {
175
261
  reactData.initialized = true;
176
- nextTick(() => {
177
- const collapseEl = refCollapseElem.value;
178
- if (collapseEl) {
179
- document.body.appendChild(collapseEl);
180
- }
181
- });
182
262
  }
183
263
  }
184
264
  reactData.isEnterCollapse = false;
@@ -188,7 +268,7 @@ export default defineVxeComponent({
188
268
  };
189
269
  const handleClickIconCollapse = (evnt, item, itemList) => {
190
270
  const { accordion } = props;
191
- const { menuEffectMaps } = internalData;
271
+ const { menuEffectMaps, menuInitMaps } = internalData;
192
272
  const { itemId, hasChild, isExpand } = item;
193
273
  const isCollapsed = computeIsCollapsed.value;
194
274
  const expanded = !isExpand;
@@ -206,6 +286,7 @@ export default defineVxeComponent({
206
286
  });
207
287
  }
208
288
  item.isExpand = expanded;
289
+ menuInitMaps[itemId] = true;
209
290
  const wrapperEl = isCollapsed ? refCollapseElem.value : refElem.value;
210
291
  if (wrapperEl) {
211
292
  const nemuEl = wrapperEl.querySelector(`.vxe-menu--item-wrapper[data-menu-id="${itemId}"]`);
@@ -243,7 +324,7 @@ export default defineVxeComponent({
243
324
  const menuOpts = computeMenuOpts.value;
244
325
  if (menuConfig ? isEnableConf(menuOpts) : menuOpts.enabled) {
245
326
  const { options, visibleMethod } = menuOpts;
246
- if (!visibleMethod || visibleMethod({ $menu: $xeMenu, options, currentMenu: item })) {
327
+ if (!visibleMethod || visibleMethod({ $menu: $xeMenu, options, currentMenu: item, currentOption: item.itemConf })) {
247
328
  if (VxeUI.contextMenu) {
248
329
  VxeUI.contextMenu.openByEvent(evnt, {
249
330
  options,
@@ -252,7 +333,7 @@ export default defineVxeComponent({
252
333
  const { option } = eventParams;
253
334
  const gMenuOpts = menus.get(option.code);
254
335
  const mmMethod = gMenuOpts ? gMenuOpts.menuMenuMethod : null;
255
- const params = { menu: option, currentMenu: item, $event: evnt, $menu: $xeMenu };
336
+ const params = { menu: option, currentMenu: item, currentOption: item.itemConf, $event: evnt, $menu: $xeMenu };
256
337
  if (mmMethod) {
257
338
  mmMethod(params, evnt);
258
339
  }
@@ -266,10 +347,11 @@ export default defineVxeComponent({
266
347
  dispatchEvent('option-menu', { currentMenu: item }, evnt);
267
348
  };
268
349
  const handleClickMenu = (evnt, item, itemList) => {
269
- const { itemKey, routerLink, hasChild } = item;
270
- if (routerLink) {
350
+ const { itemKey, linkUrl, routerLink, hasChild } = item;
351
+ if (linkUrl || routerLink) {
271
352
  emitModel(itemKey);
272
- handleMenuMouseleave();
353
+ reactData.isEnterCollapse = false;
354
+ internalData.lastActiveTime = Date.now();
273
355
  }
274
356
  else {
275
357
  if (hasChild) {
@@ -277,36 +359,26 @@ export default defineVxeComponent({
277
359
  }
278
360
  else {
279
361
  emitModel(itemKey);
280
- handleMenuMouseleave();
362
+ reactData.isEnterCollapse = false;
363
+ internalData.lastActiveTime = Date.now();
281
364
  }
282
365
  }
283
366
  const params = {
284
367
  currentMenu: item,
368
+ currentOption: item.itemConf,
369
+ option: item.itemConf,
285
370
  // 已废弃
286
371
  menu: item
287
372
  };
288
373
  dispatchEvent('click', params, evnt);
289
374
  };
290
375
  const handleMenuMouseenter = () => {
291
- const { collapseStyle } = reactData;
292
- const collapseEnterWidth = computeCollapseEnterWidth.value;
293
- reactData.collapseStyle = Object.assign({}, collapseStyle, {
294
- width: collapseEnterWidth ? toCssUnit(collapseEnterWidth) : ''
295
- });
296
- reactData.isEnterCollapse = true;
297
- };
298
- const handleMenuMouseover = () => {
299
- const { isEnterCollapse } = reactData;
300
- if (!isEnterCollapse) {
301
- handleMenuMouseenter();
376
+ const { lastActiveTime } = internalData;
377
+ if (lastActiveTime < Date.now() - 500) {
378
+ reactData.isEnterCollapse = true;
302
379
  }
303
380
  };
304
381
  const handleMenuMouseleave = () => {
305
- const { collapseStyle } = reactData;
306
- const el = refElem.value;
307
- reactData.collapseStyle = Object.assign({}, collapseStyle, {
308
- width: el ? toCssUnit(el.offsetWidth) : ''
309
- });
310
382
  reactData.isEnterCollapse = false;
311
383
  };
312
384
  const callSlot = (slotFunc, params) => {
@@ -323,8 +395,69 @@ export default defineVxeComponent({
323
395
  const dispatchEvent = (type, params, evnt) => {
324
396
  emit(type, createEvent(evnt, { $menu: $xeMenu }, params));
325
397
  };
398
+ const handleScrollToView = (itemId) => {
399
+ const wrapperEl = refElem.value;
400
+ const nemuEl = wrapperEl ? wrapperEl.querySelector(`.vxe-menu--item-wrapper[data-menu-id="${itemId}"]`) : null;
401
+ if (nemuEl) {
402
+ scrollToView(nemuEl);
403
+ return true;
404
+ }
405
+ return false;
406
+ };
326
407
  const menuMethods = {
327
- dispatchEvent
408
+ dispatchEvent,
409
+ setExpandByMenuKey(menuKeys, expanded) {
410
+ const { menuKeyMaps, menuInitMaps } = internalData;
411
+ if (menuKeys) {
412
+ if (!XEUtils.isArray(menuKeys)) {
413
+ menuKeys = [menuKeys];
414
+ }
415
+ menuKeys.forEach(mKey => {
416
+ const menuItem = menuKeyMaps[mKey];
417
+ if (menuItem) {
418
+ if (expanded) {
419
+ menuInitMaps[menuItem.itemId] = true;
420
+ }
421
+ menuItem.isExpand = !!expanded;
422
+ }
423
+ });
424
+ }
425
+ return nextTick();
426
+ },
427
+ clearAllExpandMenu() {
428
+ const { menuList } = reactData;
429
+ XEUtils.eachTree(menuList, (item) => {
430
+ item.isExpand = false;
431
+ }, { children: 'childList' });
432
+ internalData.menuInitMaps = {};
433
+ return nextTick();
434
+ },
435
+ scrollToMenuKey(menuKey) {
436
+ const { menuKeyMaps } = internalData;
437
+ const menuItem = menuKeyMaps[menuKey];
438
+ if (!menuItem) {
439
+ return nextTick();
440
+ }
441
+ const { itemId } = menuItem;
442
+ if (handleScrollToView(itemId)) {
443
+ return nextTick();
444
+ }
445
+ return nextTick().then(() => {
446
+ handleScrollToView(itemId);
447
+ });
448
+ },
449
+ scrollToActiveMenu() {
450
+ const { activeName } = reactData;
451
+ if (activeName) {
452
+ return $xeMenu.scrollToMenuKey(activeName);
453
+ }
454
+ return nextTick().then(() => {
455
+ const { activeName } = reactData;
456
+ if (activeName) {
457
+ return $xeMenu.scrollToMenuKey(activeName);
458
+ }
459
+ });
460
+ }
328
461
  };
329
462
  const menuPrivateMethods = {};
330
463
  Object.assign($xeMenu, menuMethods, menuPrivateMethods);
@@ -338,9 +471,9 @@ export default defineVxeComponent({
338
471
  const isCollapsed = computeIsCollapsed.value;
339
472
  const params = {
340
473
  currentMenu: item,
341
- collapsed: isCollapsed,
342
- // 已废弃
343
- option: item
474
+ currentOption: item.itemConf,
475
+ option: item.itemConf,
476
+ collapsed: isCollapsed
344
477
  };
345
478
  return [
346
479
  optionSlot
@@ -377,89 +510,79 @@ export default defineVxeComponent({
377
510
  ];
378
511
  };
379
512
  const renderDefaultChildren = (item, itemList) => {
380
- const { itemId, itemKey, level, hasChild, isActive, isExactActive, isExpand, routerLink, childList } = item;
513
+ const { itemId, itemKey, level, hasChild, isActive, isExactActive, isExpand, linkUrl, routerLink, linkTarget, childList } = item;
381
514
  const { isEnterCollapse } = reactData;
515
+ const { menuInitMaps } = internalData;
382
516
  const isCollapsed = computeIsCollapsed.value;
383
517
  if (item.permissionCode) {
384
518
  if (!permission.checkVisible(item.permissionCode)) {
385
519
  return renderEmptyElement($xeMenu);
386
520
  }
387
521
  }
522
+ const isExpandChild = (!isCollapsed || isEnterCollapse) && isExpand;
523
+ const linkOns = {
524
+ onContextmenu(evnt) {
525
+ handleContextmenuEvent(evnt, item);
526
+ },
527
+ onClick(evnt) {
528
+ handleClickMenu(evnt, item, itemList);
529
+ }
530
+ };
388
531
  return h('div', {
389
532
  key: itemKey,
390
533
  class: ['vxe-menu--item-wrapper', `vxe-menu--item-level${level}`, {
534
+ 'has--child': hasChild,
391
535
  'is--exact-active': isExactActive,
392
536
  'is--active': isActive,
393
- 'is--expand': (!isCollapsed || isEnterCollapse) && isExpand
537
+ 'is--expand': isExpandChild
394
538
  }],
395
539
  'data-menu-id': itemId
396
540
  }, [
397
- routerLink
398
- ? h(resolveComponent('router-link'), {
399
- class: 'vxe-menu--item-link',
400
- to: routerLink,
401
- onContextmenu(evnt) {
402
- handleContextmenuEvent(evnt, item);
403
- },
404
- onClick(evnt) {
405
- handleClickMenu(evnt, item, itemList);
406
- }
407
- }, {
408
- default: () => renderMenuTitle(item, itemList)
409
- })
410
- : h('div', {
411
- class: 'vxe-menu--item-link',
412
- onContextmenu(evnt) {
413
- handleContextmenuEvent(evnt, item);
414
- },
415
- onClick(evnt) {
416
- handleClickMenu(evnt, item, itemList);
417
- }
418
- }, renderMenuTitle(item, itemList)),
541
+ linkUrl
542
+ ? h('a', Object.assign({ class: 'vxe-menu--item-link is--link', href: linkUrl, target: linkTarget }, linkOns), renderMenuTitle(item, itemList))
543
+ : (routerLink
544
+ ? h(resolveComponent('router-link'), Object.assign({ class: 'vxe-menu--item-link is--router', to: routerLink, target: linkTarget }, linkOns), {
545
+ default: () => renderMenuTitle(item, itemList)
546
+ })
547
+ : h('div', Object.assign({ class: 'vxe-menu--item-link is--default' }, linkOns), renderMenuTitle(item, itemList))),
419
548
  hasChild
420
549
  ? h('div', {
421
550
  class: 'vxe-menu--item-group'
422
- }, childList.map(child => renderDefaultChildren(child, childList)))
551
+ }, isExpandChild || menuInitMaps[itemId] ? childList.map(child => renderDefaultChildren(child, childList)) : [])
423
552
  : renderEmptyElement($xeMenu)
424
553
  ]);
425
554
  };
426
555
  const renderCollapseChildren = (item, itemList) => {
427
- const { itemId, itemKey, level, hasChild, isActive, isExactActive, routerLink, childList } = item;
556
+ const { itemId, itemKey, level, hasChild, isActive, isExactActive, routerLink, linkUrl, linkTarget, childList } = item;
428
557
  if (item.permissionCode) {
429
558
  if (!permission.checkVisible(item.permissionCode)) {
430
559
  return renderEmptyElement($xeMenu);
431
560
  }
432
561
  }
562
+ const linkOns = {
563
+ onContextmenu(evnt) {
564
+ handleContextmenuEvent(evnt, item);
565
+ },
566
+ onClick(evnt) {
567
+ handleClickMenu(evnt, item, itemList);
568
+ }
569
+ };
433
570
  return h('div', {
434
571
  key: itemKey,
435
572
  class: ['vxe-menu--item-wrapper', `vxe-menu--item-level${level}`, {
573
+ 'has--child': hasChild,
436
574
  'is--exact-active': isExactActive,
437
575
  'is--active': isActive
438
576
  }],
439
577
  'data-menu-id': itemId
440
578
  }, [
441
- routerLink
442
- ? h(resolveComponent('router-link'), {
443
- class: 'vxe-menu--item-link',
444
- to: routerLink,
445
- onContextmenu(evnt) {
446
- handleContextmenuEvent(evnt, item);
447
- },
448
- onClick(evnt) {
449
- handleClickMenu(evnt, item, itemList);
450
- }
451
- }, {
452
- default: () => renderMenuTitle(item, itemList)
453
- })
454
- : h('div', {
455
- class: 'vxe-menu--item-link',
456
- onContextmenu(evnt) {
457
- handleContextmenuEvent(evnt, item);
458
- },
459
- onClick(evnt) {
460
- handleClickMenu(evnt, item, itemList);
461
- }
462
- }, renderMenuTitle(item, itemList)),
579
+ linkUrl
580
+ ? h('a', Object.assign({ class: 'vxe-menu--item-link is--link', href: linkUrl, target: linkTarget }, linkOns), renderMenuTitle(item, itemList))
581
+ : (routerLink
582
+ ? h(resolveComponent('router-link'), Object.assign({ class: 'vxe-menu--item-link is--router', to: routerLink, target: linkTarget }, linkOns), {
583
+ default: () => renderMenuTitle(item, itemList)
584
+ })
585
+ : h('div', Object.assign({ class: 'vxe-menu--item-link is--default' }, linkOns), renderMenuTitle(item, itemList))),
463
586
  hasChild
464
587
  ? h('div', {
465
588
  class: 'vxe-menu--item-group'
@@ -472,39 +595,67 @@ export default defineVxeComponent({
472
595
  const { initialized, menuList, collapseStyle, isEnterCollapse } = reactData;
473
596
  const vSize = computeSize.value;
474
597
  const isCollapsed = computeIsCollapsed.value;
598
+ const currBorder = computeCurrBorder.value;
599
+ const varStyle = computeVarStyle.value;
600
+ const headerSlot = slots.header;
601
+ const footerSlot = slots.footer;
475
602
  let ons = {};
476
603
  if (collapseFixed) {
477
604
  ons = {
478
605
  onMouseenter: handleMenuMouseenter,
479
- onMouseover: handleMenuMouseover,
480
606
  onMouseleave: handleMenuMouseleave
481
607
  };
482
608
  }
609
+ const stParams = { collapsed: isCollapsed };
483
610
  return h('div', {
484
611
  ref: refElem,
485
612
  class: ['vxe-menu', {
613
+ [`border--${currBorder}`]: currBorder,
486
614
  [`size--${vSize}`]: vSize,
487
615
  'is--collapsed': isCollapsed,
488
616
  'is--loading': loading
489
617
  }]
490
618
  }, [
619
+ headerSlot
620
+ ? h('div', {
621
+ class: 'vxe-menu--header'
622
+ }, headerSlot(stParams))
623
+ : renderEmptyElement($xeMenu),
491
624
  h('div', {
492
- class: 'vxe-menu--item-list'
625
+ class: 'vxe-menu--body'
493
626
  }, menuList.map(child => isCollapsed ? renderCollapseChildren(child, menuList) : renderDefaultChildren(child, menuList))),
494
- initialized
495
- ? h('div', Object.assign({ ref: refCollapseElem, class: ['vxe-menu--collapse-wrapper', {
627
+ footerSlot
628
+ ? h('div', {
629
+ class: 'vxe-menu--footer'
630
+ }, footerSlot(stParams))
631
+ : renderEmptyElement($xeMenu),
632
+ h(Teleport, {
633
+ to: 'body',
634
+ disabled: !initialized
635
+ }, [
636
+ h('div', Object.assign({ ref: refCollapseElem, class: ['vxe-menu--collapse-wrapper', {
496
637
  [`size--${vSize}`]: vSize,
497
638
  'is--collapsed': isCollapsed,
498
639
  'is--enter': isEnterCollapse,
499
640
  'is--loading': loading
500
- }], style: collapseStyle }, ons), [
501
- isCollapsed
502
- ? h('div', {
503
- class: 'vxe-menu--item-list'
504
- }, menuList.map(child => renderDefaultChildren(child, menuList)))
505
- : renderEmptyElement($xeMenu)
506
- ])
507
- : renderEmptyElement($xeMenu),
641
+ }], style: Object.assign({}, varStyle, collapseStyle) }, ons), isCollapsed
642
+ ? [
643
+ headerSlot
644
+ ? h('div', {
645
+ class: 'vxe-menu--header'
646
+ }, headerSlot(stParams))
647
+ : renderEmptyElement($xeMenu),
648
+ h('div', {
649
+ class: 'vxe-menu--body'
650
+ }, menuList.map(child => renderDefaultChildren(child, menuList))),
651
+ footerSlot
652
+ ? h('div', {
653
+ class: 'vxe-menu--footer'
654
+ }, footerSlot(stParams))
655
+ : renderEmptyElement($xeMenu)
656
+ ]
657
+ : [])
658
+ ]),
508
659
  /**
509
660
  * 加载中
510
661
  */
@@ -544,13 +695,6 @@ export default defineVxeComponent({
544
695
  updateCollapseStyle();
545
696
  });
546
697
  onBeforeUnmount(() => {
547
- const collapseEl = refCollapseElem.value;
548
- if (collapseEl) {
549
- const parentNode = collapseEl.parentNode;
550
- if (parentNode) {
551
- parentNode.removeChild(collapseEl);
552
- }
553
- }
554
698
  globalEvents.off($xeMenu, 'resize');
555
699
  XEUtils.assign(reactData, createReactData());
556
700
  XEUtils.assign(internalData, createInternalData());