vxe-pc-ui 4.14.39 → 4.15.0

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 (222) hide show
  1. package/dist/all.esm.js +1722 -728
  2. package/dist/style.css +1 -1
  3. package/dist/style.min.css +1 -1
  4. package/es/cascader/src/cascader.js +1157 -172
  5. package/es/cascader/src/util.js +7 -0
  6. package/es/cascader/style.css +197 -21
  7. package/es/cascader/style.min.css +1 -1
  8. package/es/input/src/input.js +2 -2
  9. package/es/language/ar-EG.js +7 -0
  10. package/es/language/de-DE.js +7 -0
  11. package/es/language/en-US.js +7 -0
  12. package/es/language/es-ES.js +7 -0
  13. package/es/language/fr-FR.js +7 -0
  14. package/es/language/hu-HU.js +7 -0
  15. package/es/language/hy-AM.js +7 -0
  16. package/es/language/id-ID.js +7 -0
  17. package/es/language/it-IT.js +7 -0
  18. package/es/language/ja-JP.js +7 -0
  19. package/es/language/ko-KR.js +7 -0
  20. package/es/language/ms-MY.js +7 -0
  21. package/es/language/nb-NO.js +7 -0
  22. package/es/language/pt-BR.js +7 -0
  23. package/es/language/ru-RU.js +7 -0
  24. package/es/language/th-TH.js +7 -0
  25. package/es/language/ug-CN.js +7 -0
  26. package/es/language/uk-UA.js +7 -0
  27. package/es/language/uz-UZ.js +7 -0
  28. package/es/language/vi-VN.js +7 -0
  29. package/es/language/zh-CHT.js +7 -0
  30. package/es/language/zh-CN.js +7 -0
  31. package/es/list/style.css +2 -1
  32. package/es/list/style.min.css +1 -1
  33. package/es/number-input/src/number-input.js +7 -7
  34. package/es/number-input/src/util.js +2 -2
  35. package/es/split/style.css +1 -1
  36. package/es/split/style.min.css +1 -1
  37. package/es/splitter/style.css +1 -1
  38. package/es/splitter/style.min.css +1 -1
  39. package/es/style.css +1 -1
  40. package/es/style.min.css +1 -1
  41. package/es/tree/src/tree.js +23 -21
  42. package/es/tree-select/src/tree-select.js +20 -16
  43. package/es/tree-select/style.css +1 -8
  44. package/es/tree-select/style.min.css +1 -1
  45. package/es/ui/index.js +10 -4
  46. package/es/ui/src/dom.js +2 -2
  47. package/es/ui/src/log.js +1 -1
  48. package/es/vxe-cascader/style.css +197 -21
  49. package/es/vxe-cascader/style.min.css +1 -1
  50. package/es/vxe-list/style.css +2 -1
  51. package/es/vxe-list/style.min.css +1 -1
  52. package/es/vxe-split/style.css +1 -1
  53. package/es/vxe-split/style.min.css +1 -1
  54. package/es/vxe-splitter/style.css +1 -1
  55. package/es/vxe-splitter/style.min.css +1 -1
  56. package/es/vxe-tree-select/style.css +1 -8
  57. package/es/vxe-tree-select/style.min.css +1 -1
  58. package/lib/cascader/src/cascader.js +1322 -173
  59. package/lib/cascader/src/cascader.min.js +1 -1
  60. package/lib/cascader/src/util.js +15 -0
  61. package/lib/cascader/src/util.min.js +1 -0
  62. package/lib/cascader/style/style.css +197 -21
  63. package/lib/cascader/style/style.min.css +1 -1
  64. package/lib/index.umd.js +2159 -972
  65. package/lib/index.umd.min.js +1 -1
  66. package/lib/input/src/input.js +2 -2
  67. package/lib/input/src/input.min.js +1 -1
  68. package/lib/language/ar-EG.js +7 -0
  69. package/lib/language/ar-EG.min.js +1 -1
  70. package/lib/language/ar-EG.umd.js +7 -0
  71. package/lib/language/de-DE.js +7 -0
  72. package/lib/language/de-DE.min.js +1 -1
  73. package/lib/language/de-DE.umd.js +7 -0
  74. package/lib/language/en-US.js +7 -0
  75. package/lib/language/en-US.min.js +1 -1
  76. package/lib/language/en-US.umd.js +7 -0
  77. package/lib/language/es-ES.js +7 -0
  78. package/lib/language/es-ES.min.js +1 -1
  79. package/lib/language/es-ES.umd.js +7 -0
  80. package/lib/language/fr-FR.js +7 -0
  81. package/lib/language/fr-FR.min.js +1 -1
  82. package/lib/language/fr-FR.umd.js +7 -0
  83. package/lib/language/hu-HU.js +7 -0
  84. package/lib/language/hu-HU.min.js +1 -1
  85. package/lib/language/hu-HU.umd.js +7 -0
  86. package/lib/language/hy-AM.js +7 -0
  87. package/lib/language/hy-AM.min.js +1 -1
  88. package/lib/language/hy-AM.umd.js +7 -0
  89. package/lib/language/id-ID.js +7 -0
  90. package/lib/language/id-ID.min.js +1 -1
  91. package/lib/language/id-ID.umd.js +7 -0
  92. package/lib/language/it-IT.js +7 -0
  93. package/lib/language/it-IT.min.js +1 -1
  94. package/lib/language/it-IT.umd.js +7 -0
  95. package/lib/language/ja-JP.js +7 -0
  96. package/lib/language/ja-JP.min.js +1 -1
  97. package/lib/language/ja-JP.umd.js +7 -0
  98. package/lib/language/ko-KR.js +7 -0
  99. package/lib/language/ko-KR.min.js +1 -1
  100. package/lib/language/ko-KR.umd.js +7 -0
  101. package/lib/language/ms-MY.js +7 -0
  102. package/lib/language/ms-MY.min.js +1 -1
  103. package/lib/language/ms-MY.umd.js +7 -0
  104. package/lib/language/nb-NO.js +7 -0
  105. package/lib/language/nb-NO.min.js +1 -1
  106. package/lib/language/nb-NO.umd.js +7 -0
  107. package/lib/language/pt-BR.js +7 -0
  108. package/lib/language/pt-BR.min.js +1 -1
  109. package/lib/language/pt-BR.umd.js +7 -0
  110. package/lib/language/ru-RU.js +7 -0
  111. package/lib/language/ru-RU.min.js +1 -1
  112. package/lib/language/ru-RU.umd.js +7 -0
  113. package/lib/language/th-TH.js +7 -0
  114. package/lib/language/th-TH.min.js +1 -1
  115. package/lib/language/th-TH.umd.js +7 -0
  116. package/lib/language/ug-CN.js +7 -0
  117. package/lib/language/ug-CN.min.js +1 -1
  118. package/lib/language/ug-CN.umd.js +7 -0
  119. package/lib/language/uk-UA.js +7 -0
  120. package/lib/language/uk-UA.min.js +1 -1
  121. package/lib/language/uk-UA.umd.js +7 -0
  122. package/lib/language/uz-UZ.js +7 -0
  123. package/lib/language/uz-UZ.min.js +1 -1
  124. package/lib/language/uz-UZ.umd.js +7 -0
  125. package/lib/language/vi-VN.js +7 -0
  126. package/lib/language/vi-VN.min.js +1 -1
  127. package/lib/language/vi-VN.umd.js +7 -0
  128. package/lib/language/zh-CHT.js +7 -0
  129. package/lib/language/zh-CHT.min.js +1 -1
  130. package/lib/language/zh-CHT.umd.js +7 -0
  131. package/lib/language/zh-CN.js +7 -0
  132. package/lib/language/zh-CN.min.js +1 -1
  133. package/lib/language/zh-CN.umd.js +7 -0
  134. package/lib/list/style/style.css +2 -1
  135. package/lib/list/style/style.min.css +1 -1
  136. package/lib/number-input/src/number-input.js +7 -4
  137. package/lib/number-input/src/number-input.min.js +1 -1
  138. package/lib/number-input/src/util.js +2 -2
  139. package/lib/number-input/src/util.min.js +1 -1
  140. package/lib/split/style/style.css +1 -1
  141. package/lib/split/style/style.min.css +1 -1
  142. package/lib/splitter/style/style.css +1 -1
  143. package/lib/splitter/style/style.min.css +1 -1
  144. package/lib/style.css +1 -1
  145. package/lib/style.min.css +1 -1
  146. package/lib/tree/src/tree.js +23 -21
  147. package/lib/tree/src/tree.min.js +1 -1
  148. package/lib/tree-select/src/tree-select.js +22 -17
  149. package/lib/tree-select/src/tree-select.min.js +1 -1
  150. package/lib/tree-select/style/style.css +1 -8
  151. package/lib/tree-select/style/style.min.css +1 -1
  152. package/lib/ui/index.js +10 -4
  153. package/lib/ui/index.min.js +1 -1
  154. package/lib/ui/src/dom.js +5 -3
  155. package/lib/ui/src/dom.min.js +1 -1
  156. package/lib/ui/src/log.js +1 -1
  157. package/lib/ui/src/log.min.js +1 -1
  158. package/lib/vxe-cascader/style/style.css +197 -21
  159. package/lib/vxe-cascader/style/style.min.css +1 -1
  160. package/lib/vxe-list/style/style.css +2 -1
  161. package/lib/vxe-list/style/style.min.css +1 -1
  162. package/lib/vxe-split/style/style.css +1 -1
  163. package/lib/vxe-split/style/style.min.css +1 -1
  164. package/lib/vxe-splitter/style/style.css +1 -1
  165. package/lib/vxe-splitter/style/style.min.css +1 -1
  166. package/lib/vxe-tree-select/style/style.css +1 -8
  167. package/lib/vxe-tree-select/style/style.min.css +1 -1
  168. package/package.json +1 -1
  169. package/packages/cascader/src/cascader.ts +1193 -182
  170. package/packages/cascader/src/util.ts +9 -0
  171. package/packages/input/src/input.ts +2 -2
  172. package/packages/language/ar-EG.ts +7 -0
  173. package/packages/language/de-DE.ts +7 -0
  174. package/packages/language/en-US.ts +7 -0
  175. package/packages/language/es-ES.ts +7 -0
  176. package/packages/language/fr-FR.ts +7 -0
  177. package/packages/language/hu-HU.ts +7 -0
  178. package/packages/language/hy-AM.ts +7 -0
  179. package/packages/language/id-ID.ts +7 -0
  180. package/packages/language/it-IT.ts +7 -0
  181. package/packages/language/ja-JP.ts +7 -0
  182. package/packages/language/ko-KR.ts +7 -0
  183. package/packages/language/ms-MY.ts +7 -0
  184. package/packages/language/nb-NO.ts +7 -0
  185. package/packages/language/pt-BR.ts +7 -0
  186. package/packages/language/ru-RU.ts +7 -0
  187. package/packages/language/th-TH.ts +7 -0
  188. package/packages/language/ug-CN.ts +7 -0
  189. package/packages/language/uk-UA.ts +7 -0
  190. package/packages/language/uz-UZ.ts +7 -0
  191. package/packages/language/vi-VN.ts +7 -0
  192. package/packages/language/zh-CHT.ts +7 -0
  193. package/packages/language/zh-CN.ts +7 -0
  194. package/packages/number-input/src/number-input.ts +7 -7
  195. package/packages/number-input/src/util.ts +2 -2
  196. package/packages/tree/src/tree.ts +23 -22
  197. package/packages/tree-select/src/tree-select.ts +21 -16
  198. package/packages/ui/index.ts +10 -3
  199. package/packages/ui/src/dom.ts +3 -2
  200. package/styles/components/cascader.scss +116 -21
  201. package/styles/components/list.scss +2 -1
  202. package/styles/components/splitter.scss +3 -1
  203. package/styles/components/tree-select.scss +1 -8
  204. package/styles/helpers/placement.scss +2 -2
  205. package/styles/theme/base.scss +7 -0
  206. package/styles/theme/dark.scss +9 -0
  207. package/styles/theme/light.scss +9 -0
  208. package/styles/variable.scss +8 -0
  209. package/types/components/cascader.d.ts +167 -57
  210. package/types/ui/global-icon.d.ts +5 -0
  211. /package/es/icon/{iconfont.1781503194392.ttf → iconfont.1781659237913.ttf} +0 -0
  212. /package/es/icon/{iconfont.1781503194392.woff → iconfont.1781659237913.woff} +0 -0
  213. /package/es/icon/{iconfont.1781503194392.woff2 → iconfont.1781659237913.woff2} +0 -0
  214. /package/es/{iconfont.1781503194392.ttf → iconfont.1781659237913.ttf} +0 -0
  215. /package/es/{iconfont.1781503194392.woff → iconfont.1781659237913.woff} +0 -0
  216. /package/es/{iconfont.1781503194392.woff2 → iconfont.1781659237913.woff2} +0 -0
  217. /package/lib/icon/style/{iconfont.1781503194392.ttf → iconfont.1781659237913.ttf} +0 -0
  218. /package/lib/icon/style/{iconfont.1781503194392.woff → iconfont.1781659237913.woff} +0 -0
  219. /package/lib/icon/style/{iconfont.1781503194392.woff2 → iconfont.1781659237913.woff2} +0 -0
  220. /package/lib/{iconfont.1781503194392.ttf → iconfont.1781659237913.ttf} +0 -0
  221. /package/lib/{iconfont.1781503194392.woff → iconfont.1781659237913.woff} +0 -0
  222. /package/lib/{iconfont.1781503194392.woff2 → iconfont.1781659237913.woff2} +0 -0
@@ -1,21 +1,56 @@
1
1
  import { ref, computed, h, nextTick, inject, provide, reactive, Teleport, onMounted, onUnmounted, watch } from 'vue';
2
2
  import { defineVxeComponent } from '../../ui/src/comp';
3
- import { getConfig, getI18n, getIcon, globalEvents, createEvent, useSize, renderEmptyElement } from '../../ui';
3
+ import { getConfig, getI18n, getIcon, globalEvents, createEvent, useSize, renderEmptyElement, getSlotVNs } from '../../ui';
4
4
  import { getEventTargetNode, updatePanelPlacement, toCssUnit } from '../../ui/src/dom';
5
5
  import { getLastZIndex, nextZIndex } from '../../ui/src/utils';
6
- import { deNodeValue } from '../../tree/src/util';
6
+ import { enNodeValue, deNodeValue } from './util';
7
7
  import { errLog } from '../../ui/src/log';
8
8
  import XEUtils from 'xe-utils';
9
+ import VxeListComponent from '../../list/src/list';
9
10
  import VxeInputComponent from '../../input/src/input';
10
11
  import VxeButtonComponent from '../../button/src/button';
11
- function getOptUniqueId() {
12
+ /**
13
+ * 生成节点的唯一主键
14
+ */
15
+ function getNodeUniqueId() {
12
16
  return XEUtils.uniqueId('node_');
13
17
  }
18
+ function createReactData() {
19
+ return {
20
+ initialized: false,
21
+ searchValue: '',
22
+ searchLoading: false,
23
+ currentCunkList: [],
24
+ currentItems: [],
25
+ currentNode: null,
26
+ panelIndex: 0,
27
+ panelStyle: {},
28
+ panelPlacement: null,
29
+ triggerFocusPanel: false,
30
+ visiblePanel: false,
31
+ isAniVisible: false,
32
+ isActivated: false,
33
+ selectRadioKey: null,
34
+ treeList: [],
35
+ updateExpandedFlag: 1,
36
+ updateCheckboxFlag: 1,
37
+ fullOptFlag: 1,
38
+ lazyOptFlag: 1
39
+ };
40
+ }
14
41
  function createInternalData() {
15
42
  return {
16
43
  // hpTimeout: undefined,
17
- fullOptionList: [],
18
- fullNodeMaps: {}
44
+ afterTreeList: [],
45
+ treeFullData: [],
46
+ afterVisibleList: [],
47
+ nodeMaps: {},
48
+ fullNodeMaps: {},
49
+ lazyNodeMaps: {},
50
+ indeterminateRowMaps: {},
51
+ selectCheckboxMaps: {},
52
+ treeExpandedMaps: {},
53
+ treeExpandLazyLoadedMaps: {}
19
54
  };
20
55
  }
21
56
  export default defineVxeComponent({
@@ -38,25 +73,41 @@ export default defineVxeComponent({
38
73
  },
39
74
  filterable: Boolean,
40
75
  filterConfig: Object,
76
+ showFullLabel: {
77
+ type: Boolean,
78
+ default: getConfig().cascader.showFullLabel
79
+ },
80
+ separator: {
81
+ type: String,
82
+ default: getConfig().cascader.separator
83
+ },
41
84
  multiple: Boolean,
42
85
  className: [String, Function],
43
86
  prefixIcon: String,
44
- placement: String,
45
- transform: Boolean,
46
87
  lazyOptions: Array,
47
88
  options: Array,
48
89
  optionProps: Object,
49
- zIndex: Number,
50
90
  size: {
51
91
  type: String,
52
92
  default: () => getConfig().cascader.size || getConfig().size
53
93
  },
94
+ treeConfig: Object,
95
+ radioConfig: Object,
96
+ checkboxConfig: Object,
54
97
  remote: Boolean,
55
98
  remoteConfig: Function,
56
99
  popupConfig: Object,
57
- autoClose: {
100
+ checkedClosable: {
101
+ type: Boolean,
102
+ default: () => getConfig().cascader.checkedClosable
103
+ },
104
+ clearClosable: {
58
105
  type: Boolean,
59
- default: () => getConfig().cascader.autoClose
106
+ default: () => getConfig().cascader.clearClosable
107
+ },
108
+ showCloseButton: {
109
+ type: Boolean,
110
+ default: () => getConfig().cascader.showCloseButton
60
111
  },
61
112
  showTotalButton: {
62
113
  type: Boolean,
@@ -69,16 +120,7 @@ export default defineVxeComponent({
69
120
  showClearButton: {
70
121
  type: Boolean,
71
122
  default: () => getConfig().cascader.showClearButton
72
- },
73
- transfer: {
74
- type: Boolean,
75
- default: null
76
- },
77
- /**
78
- * 已废弃,被 remote-config.queryMethod 替换
79
- * @deprecated
80
- */
81
- remoteMethod: Function
123
+ }
82
124
  },
83
125
  emits: [
84
126
  'update:modelValue',
@@ -88,7 +130,14 @@ export default defineVxeComponent({
88
130
  'blur',
89
131
  'focus',
90
132
  'click',
91
- 'node-click'
133
+ 'node-click',
134
+ 'node-expand',
135
+ 'current-change',
136
+ 'radio-change',
137
+ 'checkbox-change',
138
+ 'load-success',
139
+ 'load-error',
140
+ 'visible-change'
92
141
  ],
93
142
  setup(props, context) {
94
143
  const { emit, slots } = context;
@@ -102,21 +151,9 @@ export default defineVxeComponent({
102
151
  const refElem = ref();
103
152
  const refInput = ref();
104
153
  const refInpSearch = ref();
105
- const refTreeWrapper = ref();
154
+ const refChunkWrapper = ref();
106
155
  const refOptionPanel = ref();
107
- const refTree = ref();
108
- const reactData = reactive({
109
- initialized: false,
110
- searchValue: '',
111
- searchLoading: false,
112
- panelIndex: 0,
113
- panelStyle: {},
114
- panelPlacement: null,
115
- triggerFocusPanel: false,
116
- visiblePanel: false,
117
- isAniVisible: false,
118
- isActivated: false
119
- });
156
+ const reactData = reactive(createReactData());
120
157
  const internalData = createInternalData();
121
158
  const refMaps = {
122
159
  refElem
@@ -142,17 +179,24 @@ export default defineVxeComponent({
142
179
  return disabled;
143
180
  });
144
181
  const computeBtnTransfer = computed(() => {
145
- const { transfer } = props;
146
- if (transfer === null) {
147
- const globalTransfer = getConfig().select.transfer;
148
- if (XEUtils.isBoolean(globalTransfer)) {
149
- return globalTransfer;
150
- }
151
- if ($xeTable || $xeModal || $xeDrawer || $xeForm) {
152
- return true;
153
- }
182
+ const popupOpts = computePopupOpts.value;
183
+ const { transfer } = popupOpts;
184
+ if (XEUtils.isBoolean(transfer)) {
185
+ return transfer;
154
186
  }
155
- return transfer;
187
+ if ($xeTable || $xeModal || $xeDrawer || $xeForm) {
188
+ return true;
189
+ }
190
+ return false;
191
+ });
192
+ const computeTreeOpts = computed(() => {
193
+ return Object.assign({}, getConfig().cascader.treeConfig, props.treeConfig);
194
+ });
195
+ const computeRadioOpts = computed(() => {
196
+ return Object.assign({}, getConfig().cascader.radioConfig, props.radioConfig);
197
+ });
198
+ const computeCheckboxOpts = computed(() => {
199
+ return Object.assign({}, getConfig().cascader.checkboxConfig, props.checkboxConfig);
156
200
  });
157
201
  const computePopupOpts = computed(() => {
158
202
  return Object.assign({}, getConfig().cascader.popupConfig, props.popupConfig);
@@ -160,10 +204,6 @@ export default defineVxeComponent({
160
204
  const computePropsOpts = computed(() => {
161
205
  return props.optionProps || {};
162
206
  });
163
- const computeNodeKeyField = computed(() => {
164
- const valueField = computeValueField.value;
165
- return valueField;
166
- });
167
207
  const computeLabelField = computed(() => {
168
208
  const propsOpts = computePropsOpts.value;
169
209
  return propsOpts.label || 'label';
@@ -172,46 +212,72 @@ export default defineVxeComponent({
172
212
  const propsOpts = computePropsOpts.value;
173
213
  return propsOpts.value || 'value';
174
214
  });
215
+ const computeKeyField = computed(() => {
216
+ const treeOpts = computeTreeOpts.value;
217
+ return treeOpts.keyField || 'id';
218
+ });
219
+ const computeParentField = computed(() => {
220
+ const treeOpts = computeTreeOpts.value;
221
+ return treeOpts.parentField || 'parentId';
222
+ });
175
223
  const computeChildrenField = computed(() => {
176
- const propsOpts = computePropsOpts.value;
177
- return propsOpts.children || 'children';
224
+ const treeOpts = computeTreeOpts.value;
225
+ return treeOpts.childrenField || 'children';
226
+ });
227
+ const computeMapChildrenField = computed(() => {
228
+ const treeOpts = computeTreeOpts.value;
229
+ return treeOpts.mapChildrenField || 'mapChildren';
230
+ });
231
+ const computeHasChildField = computed(() => {
232
+ const treeOpts = computeTreeOpts.value;
233
+ return treeOpts.hasChildField || 'hasChild';
178
234
  });
179
235
  const computeRemoteOpts = computed(() => {
180
236
  return Object.assign({}, getConfig().cascader.remoteConfig, props.remoteConfig);
181
237
  });
238
+ const computeSelectVals = computed(() => {
239
+ const { modelValue } = props;
240
+ return XEUtils.eqNull(modelValue) ? [] : (XEUtils.isArray(modelValue) ? modelValue : [modelValue]);
241
+ });
182
242
  const computeSelectLabel = computed(() => {
183
- const { modelValue, lazyOptions } = props;
184
- const { fullNodeMaps } = internalData;
185
- const valueField = computeValueField.value;
243
+ const { showFullLabel } = props;
244
+ const { fullOptFlag, lazyOptFlag } = reactData;
245
+ const { fullNodeMaps, lazyNodeMaps } = internalData;
186
246
  const labelField = computeLabelField.value;
187
- const selectVals = XEUtils.eqNull(modelValue) ? [] : (XEUtils.isArray(modelValue) ? modelValue : [modelValue]);
247
+ const selectVals = computeSelectVals.value;
188
248
  return selectVals.map(val => {
189
249
  const cacheItem = fullNodeMaps[val];
190
- if (cacheItem) {
191
- return cacheItem.item[labelField];
250
+ if (fullOptFlag && cacheItem) {
251
+ return showFullLabel ? cacheItem.fullLabel : cacheItem.item[labelField];
192
252
  }
193
- if (lazyOptions) {
194
- const lazyItem = lazyOptions.find(item => item[valueField] === val);
195
- if (lazyItem) {
196
- return lazyItem[labelField];
253
+ if (lazyOptFlag) {
254
+ const lazyCacheItem = lazyNodeMaps[val];
255
+ if (lazyCacheItem) {
256
+ return showFullLabel ? lazyCacheItem.fullLabel : lazyCacheItem.item[labelField];
197
257
  }
198
258
  }
199
259
  return val;
200
260
  }).join(', ');
201
261
  });
202
262
  const computePopupWrapperStyle = computed(() => {
263
+ const { currentCunkList, panelStyle } = reactData;
203
264
  const popupOpts = computePopupOpts.value;
204
- const { height, width } = popupOpts;
205
- const stys = {};
206
- if (width) {
207
- stys.width = toCssUnit(width);
208
- }
265
+ const { height, nodeWidth, nodeHeight } = popupOpts;
266
+ const stys = Object.assign(Object.assign({}, panelStyle), { '--vxe-ui-cascader-chunk-size': currentCunkList.length });
209
267
  if (height) {
210
- stys.height = toCssUnit(height);
211
- stys.maxHeight = toCssUnit(height);
268
+ stys['--vxe-ui-cascader-chunk-height'] = toCssUnit(height);
269
+ }
270
+ if (nodeWidth) {
271
+ stys['--vxe-ui-cascader-node-width'] = toCssUnit(nodeWidth);
272
+ }
273
+ if (nodeHeight) {
274
+ stys['--vxe-ui-cascader-node-height'] = toCssUnit(nodeHeight);
212
275
  }
213
276
  return stys;
214
277
  });
278
+ const computeFilterOpts = computed(() => {
279
+ return Object.assign({}, getConfig().cascader.filterConfig, props.filterConfig);
280
+ });
215
281
  const computeMaps = {};
216
282
  const $xeCascader = {
217
283
  xID,
@@ -231,48 +297,323 @@ export default defineVxeComponent({
231
297
  const cascaderMethods = {
232
298
  dispatchEvent
233
299
  };
234
- const getNodeid = (option) => {
235
- const nodeKeyField = computeNodeKeyField.value;
236
- const nodeid = option[nodeKeyField];
237
- return nodeid ? encodeURIComponent(nodeid) : '';
300
+ const getNodeId = (node) => {
301
+ if (!node) {
302
+ return '';
303
+ }
304
+ const valueField = computeValueField.value;
305
+ const nodeKey = node[valueField];
306
+ return enNodeValue(nodeKey);
307
+ };
308
+ const isCheckedByCheckboxNodeId = (nodeid) => {
309
+ const { updateCheckboxFlag } = reactData;
310
+ const { selectCheckboxMaps } = internalData;
311
+ return !!(updateCheckboxFlag && selectCheckboxMaps[nodeid]);
238
312
  };
239
- const cacheDataMap = () => {
240
- const { transform, options } = props;
241
- const nodeKeyField = computeNodeKeyField.value;
313
+ const handleCheckedCheckboxNode = (nodeList, checked) => {
314
+ const { selectCheckboxMaps } = internalData;
315
+ const mapChildrenField = computeMapChildrenField.value;
242
316
  const childrenField = computeChildrenField.value;
317
+ const checkboxOpts = computeCheckboxOpts.value;
318
+ const { checkStrictly } = checkboxOpts;
319
+ const treeOpts = computeTreeOpts.value;
320
+ const { transform } = treeOpts;
321
+ const handleSelect = (node) => {
322
+ const nodeid = getNodeId(node);
323
+ if (checked) {
324
+ if (!selectCheckboxMaps[nodeid]) {
325
+ selectCheckboxMaps[nodeid] = node;
326
+ }
327
+ }
328
+ else {
329
+ if (selectCheckboxMaps[nodeid]) {
330
+ delete selectCheckboxMaps[nodeid];
331
+ }
332
+ }
333
+ };
334
+ if (checkStrictly) {
335
+ nodeList.forEach(handleSelect);
336
+ }
337
+ else {
338
+ XEUtils.eachTree(nodeList, handleSelect, { children: transform ? mapChildrenField : childrenField });
339
+ }
340
+ reactData.updateCheckboxFlag++;
341
+ updateCheckboxStatus();
342
+ };
343
+ const createNode = (records) => {
344
+ const valueField = computeValueField.value;
345
+ return Promise.resolve(records.map(obj => {
346
+ const item = Object.assign({}, obj);
347
+ let nodeid = getNodeId(item);
348
+ if (!nodeid) {
349
+ nodeid = getNodeUniqueId();
350
+ XEUtils.set(item, valueField, nodeid);
351
+ }
352
+ return item;
353
+ }));
354
+ };
355
+ const cacheNodeMap = () => {
356
+ const { separator } = props;
357
+ const { treeFullData } = internalData;
243
358
  const valueField = computeValueField.value;
244
- const nodeMaps = {};
359
+ const labelField = computeLabelField.value;
360
+ const childrenField = computeChildrenField.value;
245
361
  const keyMaps = {};
246
- const handleOptNode = (item, index, items, path, parent, nodes) => {
247
- let nodeid = getNodeid(item);
362
+ const fullMaps = {};
363
+ XEUtils.eachTree(treeFullData, (item, index, items, path, parenItem, nodes) => {
364
+ let nodeid = getNodeId(item);
248
365
  if (!nodeid) {
249
- nodeid = getOptUniqueId();
366
+ nodeid = getNodeUniqueId();
367
+ item[valueField] = nodeid;
250
368
  }
251
- if (keyMaps[nodeid]) {
252
- errLog('vxe.error.repeatKey', [`[tree-select] ${nodeKeyField}`, nodeid]);
369
+ const nodeVal = item[valueField];
370
+ const itemRest = {
371
+ item,
372
+ index,
373
+ $index: -1,
374
+ _index: -1,
375
+ items,
376
+ parent: parenItem,
377
+ nodes,
378
+ level: nodes.length - 1,
379
+ treeIndex: index,
380
+ lineCount: 0,
381
+ treeLoaded: false,
382
+ fullLabel: nodes.map(item => item[labelField]).join((separator || ' / '))
383
+ };
384
+ keyMaps[nodeid] = itemRest;
385
+ fullMaps[nodeVal] = itemRest;
386
+ }, { children: childrenField });
387
+ internalData.nodeMaps = keyMaps;
388
+ internalData.fullNodeMaps = fullMaps;
389
+ reactData.fullOptFlag++;
390
+ };
391
+ const updateAfterDataIndex = () => {
392
+ const { separator } = props;
393
+ const { afterTreeList, nodeMaps } = internalData;
394
+ const labelField = computeLabelField.value;
395
+ const childrenField = computeChildrenField.value;
396
+ const mapChildrenField = computeMapChildrenField.value;
397
+ const treeOpts = computeTreeOpts.value;
398
+ const { transform } = treeOpts;
399
+ let vtIndex = 0;
400
+ XEUtils.eachTree(afterTreeList, (item, index, items, path, parenItem, nodes) => {
401
+ const nodeid = getNodeId(item);
402
+ const nodeItem = nodeMaps[nodeid];
403
+ if (nodeItem) {
404
+ nodeItem.items = items;
405
+ nodeItem.treeIndex = index;
406
+ nodeItem._index = vtIndex;
253
407
  }
254
- keyMaps[nodeid] = true;
255
- const value = item[valueField];
256
- if (nodeMaps[value]) {
257
- errLog('vxe.error.repeatKey', [`[tree-select] ${valueField}`, value]);
408
+ else {
409
+ const rest = {
410
+ item,
411
+ index,
412
+ $index: -1,
413
+ _index: vtIndex,
414
+ items,
415
+ parent: parenItem,
416
+ nodes,
417
+ level: nodes.length - 1,
418
+ treeIndex: index,
419
+ lineCount: 0,
420
+ treeLoaded: false,
421
+ fullLabel: nodes.map(item => item[labelField]).join((separator || ' / '))
422
+ };
423
+ nodeMaps[nodeid] = rest;
424
+ }
425
+ vtIndex++;
426
+ }, { children: transform ? mapChildrenField : childrenField });
427
+ };
428
+ const updateAfterFullData = () => {
429
+ const { searchValue } = reactData;
430
+ const { treeFullData, lastFilterValue } = internalData;
431
+ const labelField = computeLabelField.value;
432
+ const childrenField = computeChildrenField.value;
433
+ const mapChildrenField = computeMapChildrenField.value;
434
+ const treeOpts = computeTreeOpts.value;
435
+ const { transform } = treeOpts;
436
+ const filterOpts = computeFilterOpts.value;
437
+ const { beforeFilterMethod, filterMethod, afterFilterMethod } = filterOpts;
438
+ let fullList = treeFullData;
439
+ let treeList = fullList;
440
+ let filterStr = '';
441
+ if (searchValue) {
442
+ filterStr = `${searchValue}`;
443
+ const handleSearch = filterMethod
444
+ ? (item) => {
445
+ return filterMethod({
446
+ $cascader: $xeCascader,
447
+ node: item,
448
+ filterValue: filterStr
449
+ });
450
+ }
451
+ : (item) => {
452
+ return String(item[labelField]).toLowerCase().indexOf(filterStr.toLowerCase()) > -1;
453
+ };
454
+ const bafParams = { $cascader: $xeCascader, filterValue: filterStr };
455
+ if (beforeFilterMethod) {
456
+ beforeFilterMethod(bafParams);
258
457
  }
259
- nodeMaps[value] = { item, index, items, parent, nodes };
260
- };
261
- if (options) {
262
458
  if (transform) {
263
- options.forEach((item, index, items) => {
264
- handleOptNode(item, index, items, [], null, []);
459
+ treeList = XEUtils.searchTree(treeFullData, handleSearch, {
460
+ original: true,
461
+ isEvery: true,
462
+ children: childrenField,
463
+ mapChildren: mapChildrenField
265
464
  });
465
+ fullList = treeList;
266
466
  }
267
467
  else {
268
- XEUtils.eachTree(options, handleOptNode, { children: childrenField });
468
+ fullList = treeFullData.filter(handleSearch);
469
+ }
470
+ internalData.lastFilterValue = filterStr;
471
+ nextTick(() => {
472
+ if (afterFilterMethod) {
473
+ afterFilterMethod(bafParams);
474
+ }
475
+ });
476
+ }
477
+ else {
478
+ if (transform) {
479
+ treeList = XEUtils.searchTree(treeFullData, () => true, {
480
+ original: true,
481
+ isEvery: true,
482
+ children: childrenField,
483
+ mapChildren: mapChildrenField
484
+ });
485
+ fullList = treeList;
486
+ if (lastFilterValue) {
487
+ const bafParams = { $cascader: $xeCascader, filterValue: filterStr };
488
+ if (beforeFilterMethod) {
489
+ beforeFilterMethod(bafParams);
490
+ }
491
+ // 取消筛选时自动收起
492
+ nextTick(() => {
493
+ if (afterFilterMethod) {
494
+ afterFilterMethod(bafParams);
495
+ }
496
+ });
497
+ }
498
+ }
499
+ internalData.lastFilterValue = '';
500
+ }
501
+ internalData.afterVisibleList = fullList;
502
+ internalData.afterTreeList = treeList;
503
+ updateAfterDataIndex();
504
+ };
505
+ /**
506
+ * 如果为虚拟树、则将树结构拍平
507
+ */
508
+ const handleTreeToList = () => {
509
+ const { afterTreeList, treeExpandedMaps } = internalData;
510
+ const mapChildrenField = computeMapChildrenField.value;
511
+ const treeOpts = computeTreeOpts.value;
512
+ const { transform } = treeOpts;
513
+ const expandMaps = {};
514
+ if (transform) {
515
+ const fullData = [];
516
+ XEUtils.eachTree(afterTreeList, (item, index, items, path, parentRow) => {
517
+ const nodeid = getNodeId(item);
518
+ const parentNodeid = getNodeId(parentRow);
519
+ if (!parentRow || (expandMaps[parentNodeid] && treeExpandedMaps[parentNodeid])) {
520
+ expandMaps[nodeid] = 1;
521
+ fullData.push(item);
522
+ }
523
+ }, { children: mapChildrenField });
524
+ internalData.afterVisibleList = fullData;
525
+ return fullData;
526
+ }
527
+ return internalData.afterVisibleList;
528
+ };
529
+ const handleData = (force) => {
530
+ const { nodeMaps } = internalData;
531
+ let fullList = internalData.afterVisibleList;
532
+ if (force) {
533
+ // 更新数据,处理筛选和排序
534
+ updateAfterFullData();
535
+ // 如果为虚拟树,将树结构拍平
536
+ fullList = handleTreeToList();
537
+ }
538
+ const treeList = fullList.slice(0);
539
+ treeList.forEach((item, $index) => {
540
+ const nodeid = getNodeId(item);
541
+ const itemRest = nodeMaps[nodeid];
542
+ if (itemRest) {
543
+ itemRest.$index = $index;
544
+ }
545
+ });
546
+ reactData.treeList = treeList;
547
+ };
548
+ const triggerSearchEvent = XEUtils.debounce(() => handleData(true), 350, { trailing: true });
549
+ const loadData = (list) => {
550
+ const treeOpts = computeTreeOpts.value;
551
+ const keyField = computeKeyField.value;
552
+ const parentField = computeParentField.value;
553
+ const childrenField = computeChildrenField.value;
554
+ const { rootParentValue, rootValues } = treeOpts;
555
+ const { transform } = treeOpts;
556
+ const fullData = transform
557
+ ? XEUtils.toArrayTree(list, {
558
+ key: keyField,
559
+ parentKey: parentField,
560
+ mapChildren: childrenField,
561
+ rootParentValue,
562
+ rootValues
563
+ })
564
+ : list ? list.slice(0) : [];
565
+ internalData.treeFullData = fullData;
566
+ cacheNodeMap();
567
+ handleData(true);
568
+ handleCurrentItems();
569
+ updateCurrentChunk();
570
+ return nextTick();
571
+ };
572
+ const updateCurrentChunk = () => {
573
+ const { currentItems } = reactData;
574
+ const { treeFullData } = internalData;
575
+ const childrenField = computeChildrenField.value;
576
+ const currentCunkList = [treeFullData];
577
+ if (currentItems.length) {
578
+ let chunkIndex = 0;
579
+ let stNodeid = currentItems[chunkIndex];
580
+ let optList = treeFullData;
581
+ while (stNodeid && optList && optList.length) {
582
+ stNodeid = currentItems[chunkIndex++];
583
+ const currOption = optList.find(item => stNodeid === getNodeId(item));
584
+ optList = currOption ? currOption[childrenField] : [];
585
+ if (!optList || !optList.length) {
586
+ break;
587
+ }
588
+ currentCunkList.push(optList);
589
+ }
590
+ }
591
+ reactData.currentCunkList = currentCunkList;
592
+ };
593
+ const handleCurrentItems = () => {
594
+ const { treeFullData } = internalData;
595
+ const selectVals = computeSelectVals.value;
596
+ const childrenField = computeChildrenField.value;
597
+ const stItems = [];
598
+ const expandedMaps = {};
599
+ if (selectVals.length) {
600
+ const lastVal = XEUtils.last(selectVals);
601
+ const stRest = XEUtils.findTree(treeFullData, (item) => lastVal === getNodeId(item), { children: childrenField });
602
+ if (stRest) {
603
+ const { nodes } = stRest;
604
+ nodes.forEach(item => {
605
+ const nodeid = getNodeId(item);
606
+ expandedMaps[nodeid] = true;
607
+ stItems.push(nodeid);
608
+ });
269
609
  }
270
610
  }
271
- internalData.fullOptionList = options || [];
272
- internalData.fullNodeMaps = nodeMaps;
611
+ internalData.treeExpandedMaps = expandedMaps;
612
+ reactData.currentItems = stItems;
273
613
  };
274
614
  const updateZindex = () => {
275
- const { zIndex } = props;
615
+ const popupOpts = computePopupOpts.value;
616
+ const { zIndex } = popupOpts;
276
617
  if (zIndex) {
277
618
  reactData.panelIndex = zIndex;
278
619
  }
@@ -281,7 +622,6 @@ export default defineVxeComponent({
281
622
  }
282
623
  };
283
624
  const updatePlacement = () => {
284
- const { placement } = props;
285
625
  const { panelIndex } = reactData;
286
626
  const targetElem = refElem.value;
287
627
  const panelElem = refOptionPanel.value;
@@ -289,9 +629,10 @@ export default defineVxeComponent({
289
629
  const popupOpts = computePopupOpts.value;
290
630
  const handleStyle = () => {
291
631
  const ppObj = updatePanelPlacement(targetElem, panelElem, {
292
- placement: popupOpts.placement || placement,
632
+ placement: popupOpts.placement,
293
633
  defaultPlacement: popupOpts.defaultPlacement,
294
- teleportTo: btnTransfer
634
+ teleportTo: btnTransfer,
635
+ isMinWidth: false
295
636
  });
296
637
  const panelStyle = Object.assign(ppObj.style, {
297
638
  zIndex: panelIndex
@@ -302,9 +643,9 @@ export default defineVxeComponent({
302
643
  handleStyle();
303
644
  return nextTick().then(handleStyle);
304
645
  };
305
- const showOptionPanel = () => {
646
+ const showOptionPanel = (evnt) => {
306
647
  const { loading, remote, filterable } = props;
307
- const { fullOptionList } = internalData;
648
+ const { treeFullData } = internalData;
308
649
  const isDisabled = computeIsDisabled.value;
309
650
  const remoteOpts = computeRemoteOpts.value;
310
651
  if (!loading && !isDisabled) {
@@ -315,7 +656,7 @@ export default defineVxeComponent({
315
656
  reactData.isActivated = true;
316
657
  reactData.isAniVisible = true;
317
658
  if (filterable) {
318
- if (remote && remoteOpts.enabled && remoteOpts.autoLoad && !fullOptionList.length) {
659
+ if (remote && remoteOpts.enabled && remoteOpts.autoLoad && !treeFullData.length) {
319
660
  handleSearchEvent();
320
661
  }
321
662
  }
@@ -325,13 +666,52 @@ export default defineVxeComponent({
325
666
  }, 10);
326
667
  updateZindex();
327
668
  updatePlacement();
669
+ dispatchEvent('visible-change', { visible: true }, evnt || null);
328
670
  }
329
671
  };
330
- const hideOptionPanel = () => {
672
+ const hideOptionPanel = (evnt) => {
331
673
  reactData.visiblePanel = false;
332
674
  internalData.hpTimeout = setTimeout(() => {
333
675
  reactData.isAniVisible = false;
334
676
  }, 350);
677
+ dispatchEvent('visible-change', { visible: false }, evnt || null);
678
+ };
679
+ const setCurrentNode = (node) => {
680
+ reactData.currentNode = node;
681
+ return nextTick();
682
+ };
683
+ const setAllCheckboxNode = (checked) => {
684
+ const selectMaps = {};
685
+ const childrenField = computeChildrenField.value;
686
+ const mapChildrenField = computeMapChildrenField.value;
687
+ const treeOpts = computeTreeOpts.value;
688
+ const { transform } = treeOpts;
689
+ const checkKeys = [];
690
+ const checkNodes = [];
691
+ if (checked) {
692
+ XEUtils.eachTree(internalData.afterTreeList, (node) => {
693
+ const nodeid = getNodeId(node);
694
+ checkKeys.push(nodeid);
695
+ checkNodes.push(node);
696
+ selectMaps[nodeid] = true;
697
+ }, { children: transform ? mapChildrenField : childrenField });
698
+ }
699
+ internalData.indeterminateRowMaps = {};
700
+ internalData.selectCheckboxMaps = selectMaps;
701
+ reactData.updateCheckboxFlag++;
702
+ updateCheckboxStatus();
703
+ return nextTick().then(() => {
704
+ return { checkNodeKeys: checkKeys, checkNodes };
705
+ });
706
+ };
707
+ const clearCheckboxNode = () => {
708
+ internalData.indeterminateRowMaps = {};
709
+ internalData.selectCheckboxMaps = {};
710
+ reactData.updateCheckboxFlag++;
711
+ updateCheckboxStatus();
712
+ return nextTick().then(() => {
713
+ return { checkNodeKeys: [], checkNodes: [] };
714
+ });
335
715
  };
336
716
  const changeEvent = (evnt, selectValue, node) => {
337
717
  const value = XEUtils.isArray(selectValue) ? selectValue.map(deNodeValue) : deNodeValue(selectValue);
@@ -350,38 +730,36 @@ export default defineVxeComponent({
350
730
  };
351
731
  const clearEvent = (params, evnt) => {
352
732
  clearValueEvent(evnt, null);
353
- hideOptionPanel();
733
+ hideOptionPanel(evnt);
354
734
  };
355
735
  const allCheckedPanelEvent = (params) => {
356
736
  const { $event } = params;
357
- const { multiple, autoClose } = props;
358
- const $tree = refTree.value;
737
+ const { multiple, checkedClosable } = props;
359
738
  if (multiple) {
360
- if ($tree) {
361
- $tree.setAllCheckboxNode(true).then(({ checkNodeKeys, checkNodes }) => {
362
- changeEvent($event, checkNodeKeys, checkNodes[0]);
363
- dispatchEvent('all-change', { value: checkNodeKeys }, $event);
364
- if (autoClose) {
365
- hideOptionPanel();
366
- }
367
- });
368
- }
739
+ setAllCheckboxNode(true).then(({ checkNodeKeys, checkNodes }) => {
740
+ changeEvent($event, checkNodeKeys, checkNodes[0]);
741
+ dispatchEvent('all-change', { value: checkNodeKeys }, $event);
742
+ if (checkedClosable) {
743
+ hideOptionPanel($event);
744
+ }
745
+ });
369
746
  }
370
747
  };
371
748
  const clearCheckedPanelEvent = (params) => {
372
749
  const { $event } = params;
373
- const { multiple, autoClose } = props;
374
- const $tree = refTree.value;
375
- if ($tree) {
376
- const value = multiple ? [] : null;
377
- $tree.clearCheckboxNode().then(() => {
378
- if (autoClose) {
379
- hideOptionPanel();
380
- }
381
- });
382
- changeEvent($event, value, null);
383
- dispatchEvent('clear', { value }, $event);
384
- }
750
+ const { multiple, checkedClosable } = props;
751
+ const value = multiple ? [] : null;
752
+ clearCheckboxNode().then(() => {
753
+ if (checkedClosable) {
754
+ hideOptionPanel($event);
755
+ }
756
+ });
757
+ changeEvent($event, value, null);
758
+ dispatchEvent('clear', { value }, $event);
759
+ };
760
+ const closePanelEvent = (params) => {
761
+ const { $event } = params;
762
+ hideOptionPanel($event);
385
763
  };
386
764
  const handleGlobalMousewheelEvent = (evnt) => {
387
765
  const { visiblePanel } = reactData;
@@ -393,7 +771,7 @@ export default defineVxeComponent({
393
771
  updatePlacement();
394
772
  }
395
773
  else {
396
- hideOptionPanel();
774
+ hideOptionPanel(evnt);
397
775
  }
398
776
  }
399
777
  }
@@ -406,14 +784,14 @@ export default defineVxeComponent({
406
784
  const panelElem = refOptionPanel.value;
407
785
  reactData.isActivated = getEventTargetNode(evnt, el).flag || getEventTargetNode(evnt, panelElem).flag;
408
786
  if (visiblePanel && !reactData.isActivated) {
409
- hideOptionPanel();
787
+ hideOptionPanel(evnt);
410
788
  }
411
789
  }
412
790
  };
413
- const handleGlobalBlurEvent = () => {
791
+ const handleGlobalBlurEvent = (evnt) => {
414
792
  const { visiblePanel, isActivated } = reactData;
415
793
  if (visiblePanel) {
416
- hideOptionPanel();
794
+ hideOptionPanel(evnt);
417
795
  }
418
796
  if (isActivated) {
419
797
  reactData.isActivated = false;
@@ -441,12 +819,360 @@ export default defineVxeComponent({
441
819
  });
442
820
  }
443
821
  };
822
+ const changeCurrentEvent = (evnt, node) => {
823
+ evnt.preventDefault();
824
+ const isChecked = true;
825
+ reactData.currentNode = node;
826
+ dispatchEvent('current-change', { node, checked: isChecked }, evnt);
827
+ };
828
+ const changeRadioEvent = (evnt, node) => {
829
+ evnt.preventDefault();
830
+ evnt.stopPropagation();
831
+ const { nodeMaps } = internalData;
832
+ const radioOpts = computeRadioOpts.value;
833
+ const childrenField = computeChildrenField.value;
834
+ const { checkMode, checkMethod } = radioOpts;
835
+ const nodeid = getNodeId(node);
836
+ const childList = node[childrenField];
837
+ const isExistChild = childList && childList.length > 0;
838
+ const nodeItem = nodeMaps[nodeid] || {};
839
+ const nLevel = nodeItem.level;
840
+ const isDisabled = checkMethod ? !checkMethod({ $cascader: $xeCascader, node }) : !handleVisibleOrCheckMode(checkMode, isExistChild, nLevel);
841
+ if (isDisabled) {
842
+ return;
843
+ }
844
+ const value = nodeid;
845
+ reactData.selectRadioKey = value;
846
+ changeEvent(evnt, value, node);
847
+ hideOptionPanel(evnt);
848
+ };
849
+ const handleAsyncTreeExpandChilds = (node) => {
850
+ const checkboxOpts = computeCheckboxOpts.value;
851
+ const treeOpts = computeTreeOpts.value;
852
+ const { loadMethod } = treeOpts;
853
+ const { checkStrictly } = checkboxOpts;
854
+ return new Promise(resolve => {
855
+ if (loadMethod) {
856
+ const { nodeMaps } = internalData;
857
+ const nodeid = getNodeId(node);
858
+ const nodeItem = nodeMaps[nodeid];
859
+ internalData.treeExpandLazyLoadedMaps[nodeid] = true;
860
+ Promise.resolve(loadMethod({ $cascader: $xeCascader, node })).then((childRecords) => {
861
+ const { treeExpandLazyLoadedMaps } = internalData;
862
+ nodeItem.treeLoaded = true;
863
+ if (treeExpandLazyLoadedMaps[nodeid]) {
864
+ treeExpandLazyLoadedMaps[nodeid] = false;
865
+ }
866
+ if (!XEUtils.isArray(childRecords)) {
867
+ childRecords = [];
868
+ }
869
+ if (childRecords) {
870
+ return $xeCascader.loadChildrenNode(node, childRecords).then(childRows => {
871
+ const { treeExpandedMaps } = internalData;
872
+ if (childRows.length && !treeExpandedMaps[nodeid]) {
873
+ treeExpandedMaps[nodeid] = true;
874
+ }
875
+ reactData.updateExpandedFlag++;
876
+ // 如果当前节点已选中,则展开后子节点也被选中
877
+ if (!checkStrictly && $xeCascader.isCheckedByCheckboxNodeId(nodeid)) {
878
+ handleCheckedCheckboxNode(childRows, true);
879
+ }
880
+ dispatchEvent('load-success', { node, data: childRecords }, new Event('load-success'));
881
+ return nextTick();
882
+ });
883
+ }
884
+ else {
885
+ dispatchEvent('load-success', { node, data: childRecords }, new Event('load-success'));
886
+ }
887
+ }).catch((e) => {
888
+ const { treeExpandLazyLoadedMaps } = internalData;
889
+ nodeItem.treeLoaded = false;
890
+ if (treeExpandLazyLoadedMaps[nodeid]) {
891
+ treeExpandLazyLoadedMaps[nodeid] = false;
892
+ }
893
+ dispatchEvent('load-error', { node, data: e }, new Event('load-error'));
894
+ }).finally(() => {
895
+ handleTreeToList();
896
+ handleData();
897
+ });
898
+ }
899
+ else {
900
+ resolve();
901
+ }
902
+ });
903
+ };
904
+ /**
905
+ * 展开与收起树节点
906
+ * @param nodeList
907
+ * @param expanded
908
+ * @returns
909
+ */
910
+ const handleBaseTreeExpand = (nodeList, expanded) => {
911
+ const { treeExpandLazyLoadedMaps, treeExpandedMaps } = internalData;
912
+ const { nodeMaps } = internalData;
913
+ const childrenField = computeChildrenField.value;
914
+ const hasChildField = computeHasChildField.value;
915
+ const treeOpts = computeTreeOpts.value;
916
+ const { lazy, toggleMethod } = treeOpts;
917
+ const result = [];
918
+ let validNodes = toggleMethod ? nodeList.filter((node) => toggleMethod({ $cascader: $xeCascader, expanded, node })) : nodeList;
919
+ validNodes = validNodes.length ? [validNodes[validNodes.length - 1]] : [];
920
+ // 同一级只能展开一个
921
+ const nodeid = getNodeId(validNodes[0]);
922
+ const nodeItem = nodeMaps[nodeid];
923
+ if (nodeItem) {
924
+ nodeItem.items.forEach(item => {
925
+ const itemNodeId = getNodeId(item);
926
+ if (treeExpandedMaps[itemNodeId]) {
927
+ delete treeExpandedMaps[itemNodeId];
928
+ }
929
+ });
930
+ }
931
+ const expandNodes = [];
932
+ if (expanded) {
933
+ validNodes.forEach((item) => {
934
+ const itemNodeId = getNodeId(item);
935
+ if (!treeExpandedMaps[itemNodeId]) {
936
+ const nodeItem = nodeMaps[itemNodeId];
937
+ const isLoad = lazy && item[hasChildField] && !nodeItem.treeLoaded && !treeExpandLazyLoadedMaps[itemNodeId];
938
+ // 是否使用懒加载
939
+ if (isLoad) {
940
+ result.push(handleAsyncTreeExpandChilds(item));
941
+ }
942
+ else {
943
+ if (item[childrenField] && item[childrenField].length) {
944
+ treeExpandedMaps[itemNodeId] = true;
945
+ expandNodes.push(item);
946
+ }
947
+ }
948
+ }
949
+ });
950
+ }
951
+ else {
952
+ validNodes.forEach(item => {
953
+ const itemNodeId = getNodeId(item);
954
+ if (treeExpandedMaps[itemNodeId]) {
955
+ delete treeExpandedMaps[itemNodeId];
956
+ expandNodes.push(item);
957
+ }
958
+ });
959
+ }
960
+ reactData.updateExpandedFlag++;
961
+ handleTreeToList();
962
+ handleData();
963
+ return Promise.all(result);
964
+ };
965
+ const toggleExpandEvent = (evnt, node, chunks, chunkIndex) => {
966
+ const { currentItems } = reactData;
967
+ const { treeExpandLazyLoadedMaps } = internalData;
968
+ const treeOpts = computeTreeOpts.value;
969
+ const { lazy } = treeOpts;
970
+ const stItems = currentItems.slice(0, chunkIndex);
971
+ const nodeid = getNodeId(node);
972
+ const expanded = true;
973
+ evnt.stopPropagation();
974
+ stItems.push(nodeid);
975
+ reactData.currentItems = stItems;
976
+ if (!lazy || !treeExpandLazyLoadedMaps[nodeid]) {
977
+ handleBaseTreeExpand([node], expanded);
978
+ }
979
+ setCurrentNode(node);
980
+ updateCurrentChunk();
981
+ dispatchEvent('node-expand', { node, expanded }, evnt);
982
+ };
983
+ const updateCheckboxStatus = () => {
984
+ const { selectCheckboxMaps, indeterminateRowMaps, afterTreeList } = internalData;
985
+ const childrenField = computeChildrenField.value;
986
+ const mapChildrenField = computeMapChildrenField.value;
987
+ const checkboxOpts = computeCheckboxOpts.value;
988
+ const { checkStrictly, checkMethod } = checkboxOpts;
989
+ const treeOpts = computeTreeOpts.value;
990
+ const { transform } = treeOpts;
991
+ if (!checkStrictly) {
992
+ const childRowMaps = {};
993
+ const childRowList = [];
994
+ XEUtils.eachTree(afterTreeList, (node) => {
995
+ const nodeid = getNodeId(node);
996
+ const childList = node[childrenField];
997
+ if (childList && childList.length && !childRowMaps[nodeid]) {
998
+ childRowMaps[nodeid] = 1;
999
+ childRowList.unshift([node, nodeid, childList]);
1000
+ }
1001
+ }, { children: transform ? mapChildrenField : childrenField });
1002
+ childRowList.forEach(vals => {
1003
+ const node = vals[0];
1004
+ const nodeid = vals[1];
1005
+ const childList = vals[2];
1006
+ let sLen = 0; // 已选
1007
+ let hLen = 0; // 半选
1008
+ let vLen = 0; // 有效子行
1009
+ const cLen = childList.length; // 子行
1010
+ childList.forEach(checkMethod
1011
+ ? (item) => {
1012
+ const childNodeid = getNodeId(item);
1013
+ const isSelect = selectCheckboxMaps[childNodeid];
1014
+ if (checkMethod({ $cascader: $xeCascader, node: item })) {
1015
+ if (isSelect) {
1016
+ sLen++;
1017
+ }
1018
+ else if (indeterminateRowMaps[childNodeid]) {
1019
+ hLen++;
1020
+ }
1021
+ vLen++;
1022
+ }
1023
+ else {
1024
+ if (isSelect) {
1025
+ sLen++;
1026
+ }
1027
+ else if (indeterminateRowMaps[childNodeid]) {
1028
+ hLen++;
1029
+ }
1030
+ }
1031
+ }
1032
+ : item => {
1033
+ const childNodeid = getNodeId(item);
1034
+ const isSelect = selectCheckboxMaps[childNodeid];
1035
+ if (isSelect) {
1036
+ sLen++;
1037
+ }
1038
+ else if (indeterminateRowMaps[childNodeid]) {
1039
+ hLen++;
1040
+ }
1041
+ vLen++;
1042
+ });
1043
+ let isSelected = false;
1044
+ if (cLen > 0) {
1045
+ if (vLen > 0) {
1046
+ isSelected = (sLen > 0 || hLen > 0) && sLen >= vLen;
1047
+ }
1048
+ else {
1049
+ // 如果存在子项禁用
1050
+ if ((sLen > 0 && sLen >= vLen)) {
1051
+ isSelected = true;
1052
+ }
1053
+ else if (selectCheckboxMaps[nodeid]) {
1054
+ isSelected = true;
1055
+ }
1056
+ else {
1057
+ isSelected = false;
1058
+ }
1059
+ }
1060
+ }
1061
+ else {
1062
+ // 如果无子项
1063
+ isSelected = selectCheckboxMaps[nodeid];
1064
+ }
1065
+ const halfSelect = !isSelected && (sLen > 0 || hLen > 0);
1066
+ if (isSelected) {
1067
+ selectCheckboxMaps[nodeid] = node;
1068
+ if (indeterminateRowMaps[nodeid]) {
1069
+ delete indeterminateRowMaps[nodeid];
1070
+ }
1071
+ }
1072
+ else {
1073
+ if (selectCheckboxMaps[nodeid]) {
1074
+ delete selectCheckboxMaps[nodeid];
1075
+ }
1076
+ if (halfSelect) {
1077
+ indeterminateRowMaps[nodeid] = node;
1078
+ }
1079
+ else {
1080
+ if (indeterminateRowMaps[nodeid]) {
1081
+ delete indeterminateRowMaps[nodeid];
1082
+ }
1083
+ }
1084
+ }
1085
+ });
1086
+ reactData.updateCheckboxFlag++;
1087
+ }
1088
+ };
1089
+ const changeCheckboxEvent = (evnt, node) => {
1090
+ evnt.preventDefault();
1091
+ evnt.stopPropagation();
1092
+ const { selectCheckboxMaps, nodeMaps } = internalData;
1093
+ const childrenField = computeChildrenField.value;
1094
+ const mapChildrenField = computeMapChildrenField.value;
1095
+ const checkboxOpts = computeCheckboxOpts.value;
1096
+ const { checkStrictly, checkMode, checkMethod } = checkboxOpts;
1097
+ const treeOpts = computeTreeOpts.value;
1098
+ const { transform } = treeOpts;
1099
+ const nodeid = getNodeId(node);
1100
+ const childList = node[childrenField];
1101
+ const isExistChild = childList && childList.length > 0;
1102
+ const nodeItem = nodeMaps[nodeid] || {};
1103
+ const nLevel = nodeItem.level;
1104
+ const isDisabled = checkMethod ? !checkMethod({ $cascader: $xeCascader, node }) : !handleVisibleOrCheckMode(checkMode, isExistChild, nLevel);
1105
+ if (isDisabled) {
1106
+ return;
1107
+ }
1108
+ let isChecked = false;
1109
+ if (selectCheckboxMaps[nodeid]) {
1110
+ delete selectCheckboxMaps[nodeid];
1111
+ }
1112
+ else {
1113
+ isChecked = true;
1114
+ selectCheckboxMaps[nodeid] = node;
1115
+ }
1116
+ if (!checkStrictly) {
1117
+ XEUtils.eachTree(XEUtils.get(node, transform ? mapChildrenField : childrenField), (childNode) => {
1118
+ const childNodeid = getNodeId(childNode);
1119
+ if (isChecked) {
1120
+ if (!selectCheckboxMaps[childNodeid]) {
1121
+ selectCheckboxMaps[childNodeid] = true;
1122
+ }
1123
+ }
1124
+ else {
1125
+ if (selectCheckboxMaps[childNodeid]) {
1126
+ delete selectCheckboxMaps[childNodeid];
1127
+ }
1128
+ }
1129
+ }, { children: transform ? mapChildrenField : childrenField });
1130
+ }
1131
+ reactData.updateCheckboxFlag++;
1132
+ updateCheckboxStatus();
1133
+ const nodeids = XEUtils.keys(selectCheckboxMaps);
1134
+ const value = nodeids;
1135
+ changeEvent(evnt, value, node);
1136
+ };
1137
+ const handleNodeClickEvent = (evnt, node, chunks, chunkIndex) => {
1138
+ const { multiple } = props;
1139
+ const treeOpts = computeTreeOpts.value;
1140
+ const radioOpts = computeRadioOpts.value;
1141
+ const checkboxOpts = computeCheckboxOpts.value;
1142
+ const childrenField = computeChildrenField.value;
1143
+ const mapChildrenField = computeMapChildrenField.value;
1144
+ const { transform, trigger } = treeOpts;
1145
+ const childList = node[transform ? mapChildrenField : childrenField];
1146
+ let triggerCurrent = false;
1147
+ let triggerRadio = false;
1148
+ let triggerCheckbox = false;
1149
+ let triggerExpand = false;
1150
+ triggerCurrent = true;
1151
+ changeCurrentEvent(evnt, node);
1152
+ if (trigger !== 'icon') {
1153
+ triggerExpand = true;
1154
+ toggleExpandEvent(evnt, node, chunks, chunkIndex);
1155
+ }
1156
+ if (multiple) {
1157
+ if (checkboxOpts.trigger === 'node' || (!checkboxOpts.showIcon && (!childList || !childList.length))) {
1158
+ triggerCheckbox = true;
1159
+ changeCheckboxEvent(evnt, node);
1160
+ }
1161
+ }
1162
+ else {
1163
+ if (radioOpts.trigger === 'node' || (!radioOpts.showIcon && (!childList || !childList.length))) {
1164
+ triggerRadio = true;
1165
+ changeRadioEvent(evnt, node);
1166
+ }
1167
+ }
1168
+ dispatchEvent('node-click', { node, triggerCurrent, triggerRadio, triggerCheckbox, triggerExpand }, evnt);
1169
+ };
444
1170
  const focusEvent = (evnt) => {
445
1171
  const isDisabled = computeIsDisabled.value;
446
1172
  if (!isDisabled) {
447
1173
  if (!reactData.visiblePanel) {
448
1174
  reactData.triggerFocusPanel = true;
449
- showOptionPanel();
1175
+ showOptionPanel(evnt);
450
1176
  setTimeout(() => {
451
1177
  reactData.triggerFocusPanel = false;
452
1178
  }, 150);
@@ -455,7 +1181,15 @@ export default defineVxeComponent({
455
1181
  dispatchEvent('focus', {}, evnt);
456
1182
  };
457
1183
  const clickEvent = (evnt) => {
458
- togglePanelEvent(evnt);
1184
+ evnt.preventDefault();
1185
+ if (reactData.triggerFocusPanel) {
1186
+ reactData.triggerFocusPanel = false;
1187
+ }
1188
+ else {
1189
+ if (!reactData.visiblePanel) {
1190
+ showOptionPanel(evnt);
1191
+ }
1192
+ }
459
1193
  dispatchEvent('click', {}, evnt);
460
1194
  };
461
1195
  const blurEvent = (evnt) => {
@@ -464,12 +1198,13 @@ export default defineVxeComponent({
464
1198
  };
465
1199
  const modelSearchEvent = (value) => {
466
1200
  reactData.searchValue = value;
1201
+ triggerSearchEvent(new Event('filter'));
467
1202
  };
468
1203
  const handleSearchEvent = () => {
469
- const { modelValue, remote, remoteMethod } = props;
1204
+ const { modelValue, remote } = props;
470
1205
  const { searchValue } = reactData;
471
1206
  const remoteOpts = computeRemoteOpts.value;
472
- const queryMethod = remoteOpts.queryMethod || remoteMethod;
1207
+ const queryMethod = remoteOpts.queryMethod;
473
1208
  if (remote && queryMethod && remoteOpts.enabled) {
474
1209
  reactData.searchLoading = true;
475
1210
  Promise.resolve(queryMethod({ $cascader: $xeCascader, searchValue, value: modelValue })).then(() => nextTick())
@@ -487,18 +1222,211 @@ export default defineVxeComponent({
487
1222
  }
488
1223
  else {
489
1224
  if (reactData.visiblePanel) {
490
- hideOptionPanel();
1225
+ hideOptionPanel($event);
491
1226
  }
492
1227
  else {
493
- showOptionPanel();
1228
+ showOptionPanel($event);
494
1229
  }
495
1230
  }
496
1231
  };
497
- const cascaderPrivateMethods = {};
1232
+ const cascaderPrivateMethods = {
1233
+ isCheckedByCheckboxNodeId,
1234
+ /**
1235
+ * 用于树结构,给行数据加载子节点
1236
+ */
1237
+ loadChildrenNode(node, childRecords) {
1238
+ const { separator } = props;
1239
+ const { nodeMaps } = internalData;
1240
+ const treeOpts = computeTreeOpts.value;
1241
+ const labelField = computeLabelField.value;
1242
+ const { lazy, transform } = treeOpts;
1243
+ if (!lazy) {
1244
+ return Promise.resolve([]);
1245
+ }
1246
+ const childrenField = computeChildrenField.value;
1247
+ const mapChildrenField = computeMapChildrenField.value;
1248
+ const parentNodeItem = nodeMaps[getNodeId(node)];
1249
+ const parentLevel = parentNodeItem ? parentNodeItem.level : 0;
1250
+ const parentNodes = parentNodeItem ? parentNodeItem.nodes : [];
1251
+ return createNode(childRecords).then((nodeList) => {
1252
+ XEUtils.eachTree(nodeList, (childRow, index, items, path, parent, nodes) => {
1253
+ const itemNodeId = getNodeId(childRow);
1254
+ nodeMaps[itemNodeId] = {
1255
+ item: childRow,
1256
+ index: -1,
1257
+ $index: -1,
1258
+ _index: -1,
1259
+ items,
1260
+ parent: parent || parentNodeItem.item,
1261
+ nodes: parentNodes.concat(nodes),
1262
+ level: parentLevel + nodes.length,
1263
+ treeIndex: -1,
1264
+ lineCount: 0,
1265
+ treeLoaded: false,
1266
+ fullLabel: nodes.map(item => item[labelField]).join((separator || ' / '))
1267
+ };
1268
+ }, { children: childrenField });
1269
+ node[childrenField] = nodeList;
1270
+ if (transform) {
1271
+ node[mapChildrenField] = nodeList;
1272
+ }
1273
+ updateAfterDataIndex();
1274
+ return nodeList;
1275
+ });
1276
+ }
1277
+ };
498
1278
  Object.assign($xeCascader, cascaderMethods, cascaderPrivateMethods);
1279
+ const handleVisibleOrCheckMode = (mode, isExistChild, nLevel) => {
1280
+ if (mode) {
1281
+ if (mode === 'first') {
1282
+ return !nLevel;
1283
+ }
1284
+ if (mode === 'last') {
1285
+ return !isExistChild;
1286
+ }
1287
+ }
1288
+ return true;
1289
+ };
1290
+ const renderRadio = (node, isExistChild, nLevel, isChecked) => {
1291
+ const radioOpts = computeRadioOpts.value;
1292
+ const { showIcon, checkMode, checkMethod, visibleMode, visibleMethod } = radioOpts;
1293
+ const isVisible = visibleMethod ? visibleMethod({ $cascader: $xeCascader, node }) : handleVisibleOrCheckMode(visibleMode, isExistChild, nLevel);
1294
+ if (showIcon && isVisible) {
1295
+ const isDisabled = checkMethod ? !checkMethod({ $cascader: $xeCascader, node }) : !handleVisibleOrCheckMode(checkMode, isExistChild, nLevel);
1296
+ return h('div', {
1297
+ class: ['vxe-tree--radio-option', {
1298
+ 'is--checked': isChecked,
1299
+ 'is--disabled': isDisabled
1300
+ }],
1301
+ onClick: (evnt) => {
1302
+ if (!isDisabled) {
1303
+ changeRadioEvent(evnt, node);
1304
+ }
1305
+ }
1306
+ }, [
1307
+ h('span', {
1308
+ class: ['vxe-radio--icon', isChecked ? getIcon().RADIO_CHECKED : getIcon().RADIO_UNCHECKED]
1309
+ })
1310
+ ]);
1311
+ }
1312
+ return renderEmptyElement($xeCascader);
1313
+ };
1314
+ const renderCheckbox = (node, isExistChild, nLevel, isChecked, isIndeterminate) => {
1315
+ const checkboxOpts = computeCheckboxOpts.value;
1316
+ const { showIcon, checkMode, checkMethod, visibleMode, visibleMethod } = checkboxOpts;
1317
+ const isVisible = visibleMethod ? visibleMethod({ $cascader: $xeCascader, node }) : handleVisibleOrCheckMode(visibleMode, isExistChild, nLevel);
1318
+ if (showIcon && isVisible) {
1319
+ const isDisabled = checkMethod ? !checkMethod({ $cascader: $xeCascader, node }) : !handleVisibleOrCheckMode(checkMode, isExistChild, nLevel);
1320
+ return h('div', {
1321
+ class: ['vxe-cascader--checkbox-option', {
1322
+ 'is--checked': isChecked,
1323
+ 'is--indeterminate': isIndeterminate,
1324
+ 'is--disabled': isDisabled
1325
+ }],
1326
+ onClick: (evnt) => {
1327
+ if (!isDisabled) {
1328
+ changeCheckboxEvent(evnt, node);
1329
+ }
1330
+ }
1331
+ }, [
1332
+ h('span', {
1333
+ class: ['vxe-checkbox--icon', isIndeterminate ? getIcon().CHECKBOX_INDETERMINATE : (isChecked ? getIcon().CHECKBOX_CHECKED : getIcon().CHECKBOX_UNCHECKED)]
1334
+ })
1335
+ ]);
1336
+ }
1337
+ return renderEmptyElement($xeCascader);
1338
+ };
1339
+ const renderNode = (node, nodeid, nodeIndex, chunks, chunkIndex) => {
1340
+ const { multiple } = props;
1341
+ const { currentNode, selectRadioKey, updateCheckboxFlag, updateExpandedFlag } = reactData;
1342
+ const { nodeMaps, selectCheckboxMaps, indeterminateRowMaps, treeExpandedMaps, treeExpandLazyLoadedMaps } = internalData;
1343
+ const treeOpts = computeTreeOpts.value;
1344
+ const { lazy, iconLoaded, iconOpen, iconClose } = treeOpts;
1345
+ const childrenField = computeChildrenField.value;
1346
+ const labelField = computeLabelField.value;
1347
+ const hasChildField = computeHasChildField.value;
1348
+ const childList = node[childrenField];
1349
+ const isExistChild = childList && childList.length > 0;
1350
+ const iconSlot = slots.icon;
1351
+ const titleSlot = slots.title;
1352
+ const isExpand = updateExpandedFlag && treeExpandedMaps[nodeid];
1353
+ const nodeItem = nodeMaps[nodeid] || {};
1354
+ const nodeTitle = node[labelField];
1355
+ const nLevel = nodeItem.level;
1356
+ let isRadioChecked = false;
1357
+ if (!multiple) {
1358
+ isRadioChecked = nodeid === selectRadioKey;
1359
+ }
1360
+ let isCheckboxChecked = false;
1361
+ let isIndeterminate = false;
1362
+ if (multiple) {
1363
+ isCheckboxChecked = !!(updateCheckboxFlag && selectCheckboxMaps[nodeid]);
1364
+ isIndeterminate = !!(updateCheckboxFlag && indeterminateRowMaps[nodeid]);
1365
+ }
1366
+ let hasLazyChilds = false;
1367
+ let isLazyLoading = false;
1368
+ let isLazyLoaded = false;
1369
+ if (lazy) {
1370
+ isLazyLoading = !!treeExpandLazyLoadedMaps[nodeid];
1371
+ hasLazyChilds = node[hasChildField];
1372
+ isLazyLoaded = !!nodeItem.treeLoaded;
1373
+ }
1374
+ const nParams = { node };
1375
+ return h('div', {
1376
+ key: `${chunkIndex}_${nodeIndex}`,
1377
+ class: ['vxe-cascader-chunk--node-item', {
1378
+ 'is--current': currentNode && (currentNode === node || getNodeId(currentNode) === nodeid),
1379
+ 'is-radio--checked': isRadioChecked,
1380
+ 'is-checkbox--checked': isCheckboxChecked,
1381
+ 'is-checkbox--indeterminate': isIndeterminate,
1382
+ 'is--expand': isExpand
1383
+ }],
1384
+ title: nodeTitle,
1385
+ onMousedown: (evnt) => {
1386
+ const isLeftBtn = evnt.button === 0;
1387
+ if (isLeftBtn) {
1388
+ evnt.stopPropagation();
1389
+ }
1390
+ },
1391
+ onClick(evnt) {
1392
+ handleNodeClickEvent(evnt, node, chunks, chunkIndex);
1393
+ }
1394
+ }, [
1395
+ multiple ? renderCheckbox(node, isExistChild, nLevel, isCheckboxChecked, isIndeterminate) : renderRadio(node, isExistChild, nLevel, isRadioChecked),
1396
+ h('div', {
1397
+ class: 'vxe-cascader-chunk--node-item-inner'
1398
+ }, [
1399
+ h('div', {
1400
+ class: 'vxe-cascader-chunk--node-item-title'
1401
+ }, titleSlot ? getSlotVNs(titleSlot(nParams)) : nodeTitle)
1402
+ ]),
1403
+ treeOpts.showIcon && (lazy ? (isLazyLoaded ? isExistChild : hasLazyChilds) : isExistChild)
1404
+ ? h('div', {
1405
+ class: 'vxe-cascader-chunk--node-item-switcher'
1406
+ }, [
1407
+ [
1408
+ h('div', {
1409
+ class: 'vxe-cascader--node-item-icon',
1410
+ onClick(evnt) {
1411
+ if (treeOpts.trigger === 'icon') {
1412
+ toggleExpandEvent(evnt, node, chunks, chunkIndex);
1413
+ }
1414
+ }
1415
+ }, iconSlot
1416
+ ? getSlotVNs(iconSlot(nParams))
1417
+ : [
1418
+ h('i', {
1419
+ class: isLazyLoading ? (iconLoaded || getIcon().CASCADER_NODE_LOADED) : (isExpand ? (iconOpen || getIcon().CASCADER_NODE_OPEN) : (iconClose || getIcon().CASCADER_NODE_CLOSE))
1420
+ })
1421
+ ])
1422
+ ]
1423
+ ])
1424
+ : renderEmptyElement($xeCascader)
1425
+ ]);
1426
+ };
499
1427
  const renderVN = () => {
500
- const { className, modelValue, multiple, loading, filterable, showTotalButton, showCheckedButton, showClearButton } = props;
501
- const { initialized, isActivated, isAniVisible, visiblePanel, searchValue } = reactData;
1428
+ const { className, modelValue, multiple, loading, filterable, showTotalButton, showCheckedButton, showClearButton, showCloseButton } = props;
1429
+ const { initialized, isActivated, isAniVisible, visiblePanel, searchValue, currentCunkList } = reactData;
502
1430
  const vSize = computeSize.value;
503
1431
  const isDisabled = computeIsDisabled.value;
504
1432
  const selectLabel = computeSelectLabel.value;
@@ -566,7 +1494,7 @@ export default defineVxeComponent({
566
1494
  'ani--enter': !loading && visiblePanel
567
1495
  }],
568
1496
  placement: reactData.panelPlacement,
569
- style: reactData.panelStyle
1497
+ style: popupWrapperStyle
570
1498
  }, initialized
571
1499
  ? [
572
1500
  h('div', {
@@ -589,38 +1517,35 @@ export default defineVxeComponent({
589
1517
  })
590
1518
  ])
591
1519
  : renderEmptyElement($xeCascader),
592
- showTotalButton || (showCheckedButton && multiple) || showClearButton || headerSlot
1520
+ (showCheckedButton && multiple) || showClearButton || headerSlot
593
1521
  ? h('div', {
594
- class: 'vxe-cascader--panel-header'
1522
+ class: 'vxe-tree-select--panel-header'
595
1523
  }, headerSlot
596
1524
  ? headerSlot({})
597
1525
  : [
598
1526
  h('div', {
599
- class: 'vxe-cascader--header-button'
1527
+ class: 'vxe-tree-select--header-button'
600
1528
  }, [
601
- showTotalButton
1529
+ showCheckedButton && showClearButton
602
1530
  ? h('div', {
603
- class: 'vxe-cascader--header-total'
604
- }, getI18n('vxe.cascader.total', [selectVals.length]))
605
- : renderEmptyElement($xeCascader),
606
- h('div', {
607
- class: 'vxe-cascader--header-btns'
608
- }, [
609
- (showCheckedButton && multiple)
610
- ? h(VxeButtonComponent, {
611
- content: getI18n('vxe.cascader.allChecked'),
612
- mode: 'text',
613
- onClick: allCheckedPanelEvent
614
- })
615
- : renderEmptyElement($xeCascader),
616
- showClearButton
617
- ? h(VxeButtonComponent, {
618
- content: getI18n('vxe.cascader.clearChecked'),
619
- mode: 'text',
620
- onClick: clearCheckedPanelEvent
621
- })
622
- : renderEmptyElement($xeCascader)
623
- ])
1531
+ class: 'vxe-tree-select--selected-btns'
1532
+ }, [
1533
+ (showCheckedButton && multiple)
1534
+ ? h(VxeButtonComponent, {
1535
+ content: getI18n('vxe.treeSelect.allChecked'),
1536
+ mode: 'text',
1537
+ onClick: allCheckedPanelEvent
1538
+ })
1539
+ : renderEmptyElement($xeCascader),
1540
+ showClearButton
1541
+ ? h(VxeButtonComponent, {
1542
+ content: getI18n('vxe.treeSelect.clearChecked'),
1543
+ mode: 'text',
1544
+ onClick: clearCheckedPanelEvent
1545
+ })
1546
+ : renderEmptyElement($xeCascader)
1547
+ ])
1548
+ : renderEmptyElement($xeCascader)
624
1549
  ])
625
1550
  ])
626
1551
  : renderEmptyElement($xeCascader),
@@ -628,15 +1553,56 @@ export default defineVxeComponent({
628
1553
  class: 'vxe-cascader--panel-body'
629
1554
  }, [
630
1555
  h('div', {
631
- ref: refTreeWrapper,
632
- class: 'vxe-cascader-tree--wrapper',
633
- style: popupWrapperStyle
634
- }, [])
1556
+ ref: refChunkWrapper,
1557
+ class: 'vxe-cascader-chunk--wrapper'
1558
+ }, [
1559
+ currentCunkList.map((chunks, chunkIndex) => {
1560
+ return h('div', {
1561
+ key: chunkIndex,
1562
+ class: 'vxe-cascader-chunk--item-wrapper'
1563
+ }, [
1564
+ h(VxeListComponent, {
1565
+ data: chunks
1566
+ }, {
1567
+ default(slotParams) {
1568
+ const { items } = slotParams;
1569
+ return items.map((node, nodeIndex) => {
1570
+ const nodeid = getNodeId(node);
1571
+ return renderNode(node, nodeid, nodeIndex, chunks, chunkIndex);
1572
+ });
1573
+ }
1574
+ })
1575
+ ]);
1576
+ })
1577
+ ])
635
1578
  ]),
636
- footerSlot
1579
+ footerSlot || showTotalButton || (showCloseButton && multiple)
637
1580
  ? h('div', {
638
1581
  class: 'vxe-cascader--panel-footer'
639
- }, footerSlot({}))
1582
+ }, footerSlot
1583
+ ? footerSlot({})
1584
+ : [
1585
+ h('div', {
1586
+ class: 'vxe-cascader--footer-button'
1587
+ }, [
1588
+ showTotalButton
1589
+ ? h('div', {
1590
+ class: 'vxe-cascader--total-btns'
1591
+ }, getI18n('vxe.treeSelect.total', [selectVals.length]))
1592
+ : renderEmptyElement($xeCascader),
1593
+ showCloseButton && multiple
1594
+ ? h('div', {
1595
+ class: 'vxe-cascader--oper-btns'
1596
+ }, [
1597
+ h(VxeButtonComponent, {
1598
+ content: getI18n('vxe.select.close'),
1599
+ mode: 'text',
1600
+ onClick: closePanelEvent
1601
+ })
1602
+ ])
1603
+ : renderEmptyElement($xeCascader)
1604
+ ])
1605
+ ])
640
1606
  : renderEmptyElement($xeCascader)
641
1607
  ])
642
1608
  ]
@@ -644,11 +1610,30 @@ export default defineVxeComponent({
644
1610
  ])
645
1611
  ]);
646
1612
  };
1613
+ watch(() => props.modelValue, () => {
1614
+ if (!reactData.visiblePanel) {
1615
+ handleCurrentItems();
1616
+ updateCurrentChunk();
1617
+ }
1618
+ });
1619
+ watch(() => props.options, () => {
1620
+ cacheNodeMap();
1621
+ });
1622
+ const dataFlag = ref(0);
1623
+ watch(() => props.options ? props.options.length : 0, () => {
1624
+ dataFlag.value++;
1625
+ });
647
1626
  watch(() => props.options, () => {
648
- cacheDataMap();
1627
+ dataFlag.value++;
1628
+ });
1629
+ watch(dataFlag, () => {
1630
+ loadData(props.options || []);
649
1631
  });
650
- cacheDataMap();
1632
+ loadData(props.options || []);
651
1633
  onMounted(() => {
1634
+ if (props.filterable) {
1635
+ errLog('vxe.error.notProp', ['filterable']);
1636
+ }
652
1637
  globalEvents.on($xeCascader, 'mousewheel', handleGlobalMousewheelEvent);
653
1638
  globalEvents.on($xeCascader, 'mousedown', handleGlobalMousedownEvent);
654
1639
  globalEvents.on($xeCascader, 'blur', handleGlobalBlurEvent);