vxe-pc-ui 3.14.39 → 3.14.40

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