vxe-pc-ui 4.20.25 → 4.20.26

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 (626) hide show
  1. package/dist/all.esm.js +15059 -10308
  2. package/dist/style.css +1 -1
  3. package/dist/style.mini.css +1 -1
  4. package/es/alert/src/alert.js +61 -36
  5. package/es/anchor/src/anchor-link.js +39 -20
  6. package/es/anchor/src/anchor.js +74 -45
  7. package/es/avatar/src/avatar.js +47 -27
  8. package/es/backtop/src/backtop.js +65 -40
  9. package/es/badge/src/badge.js +32 -16
  10. package/es/breadcrumb/src/breadcrumb-item.js +52 -27
  11. package/es/breadcrumb/src/breadcrumb.js +11 -8
  12. package/es/button/src/button-group.js +24 -18
  13. package/es/button/src/button.js +284 -185
  14. package/es/calendar/src/calendar.js +571 -358
  15. package/es/card/src/card.js +123 -68
  16. package/es/carousel/src/carousel-item.js +14 -7
  17. package/es/carousel/src/carousel.js +174 -112
  18. package/es/cascader/src/cascader.js +526 -380
  19. package/es/checkbox/src/button.js +90 -55
  20. package/es/checkbox/src/checkbox.js +60 -40
  21. package/es/checkbox/src/group.js +34 -26
  22. package/es/collapse/src/collapse-pane.js +33 -16
  23. package/es/collapse/src/collapse.js +133 -79
  24. package/es/color-picker/src/color-picker.js +489 -350
  25. package/es/components.d.ts +3 -1
  26. package/es/components.js +3 -2
  27. package/es/context-menu/src/context-menu.js +190 -110
  28. package/es/countdown/src/countdown.js +91 -59
  29. package/es/date-panel/src/date-panel.js +760 -450
  30. package/es/date-picker/src/date-picker.js +331 -228
  31. package/es/date-range-picker/src/date-range-picker.js +366 -265
  32. package/es/divider/src/divider.js +26 -12
  33. package/es/drawer/src/drawer.js +254 -154
  34. package/es/dynamics/index.js +38 -25
  35. package/es/empty/src/empty.js +53 -29
  36. package/es/form/render/index.js +66 -41
  37. package/es/form/src/form-config-item.js +22 -16
  38. package/es/form/src/form-group.js +23 -14
  39. package/es/form/src/form-item.js +23 -17
  40. package/es/form/src/form.js +139 -95
  41. package/es/form/src/itemInfo.js +2 -1
  42. package/es/form/src/render.js +207 -127
  43. package/es/form/src/util.js +8 -4
  44. package/es/icon/src/icon.js +14 -10
  45. package/es/icon/style.css +1 -1
  46. package/es/icon/style.mini.css +1 -1
  47. package/es/icon-picker/src/icon-picker.js +250 -157
  48. package/es/image/src/group.js +26 -20
  49. package/es/image/src/image.js +33 -32
  50. package/es/image/src/preview.js +182 -122
  51. package/es/image/src/util.js +6 -3
  52. package/es/index.esm.js +9 -8
  53. package/es/index.js +9 -8
  54. package/es/input/src/input.js +820 -507
  55. package/es/layout-aside/src/layout-aside.js +54 -38
  56. package/es/layout-body/src/layout-body.js +39 -27
  57. package/es/layout-container/src/layout-container.js +16 -9
  58. package/es/layout-footer/src/layout-footer.js +16 -7
  59. package/es/layout-header/src/layout-header.js +15 -7
  60. package/es/link/src/link.js +65 -44
  61. package/es/list/src/list.js +453 -333
  62. package/es/loading/index.js +8 -5
  63. package/es/loading/src/loading.js +60 -33
  64. package/es/mention/src/mention.js +2 -1
  65. package/es/menu/src/menu.js +341 -210
  66. package/es/modal/index.js +60 -37
  67. package/es/modal/src/modal.js +303 -205
  68. package/es/notice-bar/src/notice-bar.js +64 -37
  69. package/es/number-input/src/number-input.js +249 -172
  70. package/es/pager/src/pager.js +346 -202
  71. package/es/password-input/src/password-input.js +145 -105
  72. package/es/print/src/page-break.js +2 -1
  73. package/es/print/src/print.js +184 -99
  74. package/es/pulldown/src/pulldown.js +113 -71
  75. package/es/radio/src/button.js +92 -57
  76. package/es/radio/src/group.js +33 -25
  77. package/es/radio/src/radio.js +61 -41
  78. package/es/rate/src/rate.js +48 -36
  79. package/es/result/src/result.js +67 -35
  80. package/es/row/src/col.js +30 -16
  81. package/es/row/src/row.js +21 -14
  82. package/es/scrollbar/src/scrollbar.js +177 -145
  83. package/es/segmented/src/segmented.js +93 -60
  84. package/es/select/src/optgroup.js +7 -3
  85. package/es/select/src/select.js +483 -340
  86. package/es/select/src/util.js +6 -3
  87. package/es/slider/src/slider.js +108 -80
  88. package/es/space/src/space.js +40 -23
  89. package/es/splitter/src/splitter-panel.js +50 -25
  90. package/es/splitter/src/splitter.js +219 -144
  91. package/es/steps/src/steps.js +10 -5
  92. package/es/style.css +1 -1
  93. package/es/style.mini.css +1 -1
  94. package/es/switch/src/switch.js +85 -57
  95. package/es/table-select/src/table-select.js +232 -153
  96. package/es/table-transfer/src/table-transfer.js +10 -5
  97. package/es/tabs/src/tab-pane.js +33 -16
  98. package/es/tabs/src/tabs.js +363 -230
  99. package/es/tag/src/tag.js +61 -43
  100. package/es/text/src/text.js +89 -65
  101. package/es/text-ellipsis/src/text-ellipsis.js +82 -51
  102. package/es/textarea/src/textarea.js +116 -86
  103. package/es/timeline/src/timeline-item.js +2 -1
  104. package/es/timeline/src/timeline.js +2 -1
  105. package/es/tip/src/tip.js +53 -29
  106. package/es/tooltip/src/tooltip.js +114 -74
  107. package/es/tour/src/tour.js +2 -1
  108. package/es/transfer/src/transfer.js +42 -25
  109. package/es/tree/src/tree.js +709 -492
  110. package/es/tree-select/src/tree-select.js +320 -225
  111. package/es/ui/index.d.ts +0 -1
  112. package/es/ui/index.js +46 -3
  113. package/es/ui/src/dom.js +9 -6
  114. package/es/ui/src/log.js +1 -1
  115. package/es/ui/src/utils.d.ts +1 -1
  116. package/es/upload/src/upload.js +614 -398
  117. package/es/vxe-icon/style.css +1 -1
  118. package/es/vxe-icon/style.mini.css +1 -1
  119. package/es/watermark/src/util.js +15 -12
  120. package/es/watermark/src/watermark.js +55 -25
  121. package/lib/alert/src/alert.js +62 -37
  122. package/lib/anchor/src/anchor-link.js +39 -20
  123. package/lib/anchor/src/anchor.js +75 -46
  124. package/lib/avatar/src/avatar.js +52 -32
  125. package/lib/backtop/src/backtop.js +81 -56
  126. package/lib/badge/src/badge.js +35 -19
  127. package/lib/breadcrumb/src/breadcrumb-item.js +52 -27
  128. package/lib/breadcrumb/src/breadcrumb.js +13 -10
  129. package/lib/button/src/button-group.js +27 -21
  130. package/lib/button/src/button.js +306 -207
  131. package/lib/calendar/src/calendar.js +575 -362
  132. package/lib/card/src/card.js +133 -78
  133. package/lib/carousel/src/carousel-item.js +15 -8
  134. package/lib/carousel/src/carousel.js +182 -120
  135. package/lib/cascader/src/cascader.js +555 -409
  136. package/lib/checkbox/src/button.js +93 -58
  137. package/lib/checkbox/src/checkbox.js +63 -43
  138. package/lib/checkbox/src/group.js +37 -29
  139. package/lib/collapse/src/collapse-pane.js +34 -17
  140. package/lib/collapse/src/collapse.js +139 -85
  141. package/lib/color-picker/src/color-picker.js +516 -377
  142. package/lib/components.js +3 -2
  143. package/lib/context-menu/src/context-menu.js +212 -132
  144. package/lib/countdown/src/countdown.js +95 -63
  145. package/lib/date-panel/src/date-panel.js +776 -466
  146. package/lib/date-picker/src/date-picker.js +377 -274
  147. package/lib/date-range-picker/src/date-range-picker.js +401 -300
  148. package/lib/divider/src/divider.js +31 -17
  149. package/lib/drawer/src/drawer.js +255 -155
  150. package/lib/dynamics/index.js +38 -25
  151. package/lib/empty/src/empty.js +55 -31
  152. package/lib/form/render/index.js +68 -43
  153. package/lib/form/src/form-config-item.js +24 -18
  154. package/lib/form/src/form-group.js +25 -16
  155. package/lib/form/src/form-item.js +25 -19
  156. package/lib/form/src/form.js +140 -96
  157. package/lib/form/src/itemInfo.js +4 -3
  158. package/lib/form/src/render.js +214 -134
  159. package/lib/form/src/util.js +9 -5
  160. package/lib/icon/src/icon.js +17 -13
  161. package/lib/icon/style/style.css +1 -1
  162. package/lib/icon/style/style.mini.css +1 -1
  163. package/lib/icon-picker/src/icon-picker.js +251 -158
  164. package/lib/image/src/group.js +26 -20
  165. package/lib/image/src/image.js +41 -40
  166. package/lib/image/src/preview.js +206 -146
  167. package/lib/image/src/util.js +6 -3
  168. package/lib/index.common.js +9 -8
  169. package/lib/index.js +9 -8
  170. package/lib/index.umd.js +15131 -10364
  171. package/lib/index.umd.min.js +3 -3
  172. package/lib/input/src/input.js +878 -565
  173. package/lib/layout-aside/src/layout-aside.js +61 -45
  174. package/lib/layout-body/src/layout-body.js +47 -35
  175. package/lib/layout-container/src/layout-container.js +18 -11
  176. package/lib/layout-footer/src/layout-footer.js +17 -8
  177. package/lib/layout-header/src/layout-header.js +16 -8
  178. package/lib/link/src/link.js +69 -48
  179. package/lib/list/src/list.js +456 -336
  180. package/lib/loading/index.js +8 -5
  181. package/lib/loading/src/loading.js +69 -42
  182. package/lib/mention/src/mention.js +4 -3
  183. package/lib/menu/src/menu.js +351 -220
  184. package/lib/modal/index.js +60 -37
  185. package/lib/modal/src/modal.js +306 -208
  186. package/lib/notice-bar/src/notice-bar.js +70 -43
  187. package/lib/number-input/src/number-input.js +290 -213
  188. package/lib/pager/src/pager.js +347 -203
  189. package/lib/password-input/src/password-input.js +155 -115
  190. package/lib/print/src/page-break.js +3 -2
  191. package/lib/print/src/print.js +193 -108
  192. package/lib/pulldown/src/pulldown.js +128 -86
  193. package/lib/radio/src/button.js +96 -61
  194. package/lib/radio/src/group.js +37 -29
  195. package/lib/radio/src/radio.js +65 -45
  196. package/lib/rate/src/rate.js +50 -38
  197. package/lib/result/src/result.js +68 -36
  198. package/lib/row/src/col.js +32 -18
  199. package/lib/row/src/row.js +25 -18
  200. package/lib/scrollbar/src/scrollbar.js +178 -146
  201. package/lib/segmented/src/segmented.js +97 -64
  202. package/lib/select/src/optgroup.js +7 -3
  203. package/lib/select/src/select.js +486 -343
  204. package/lib/select/src/util.js +6 -3
  205. package/lib/slider/src/slider.js +122 -94
  206. package/lib/space/src/space.js +54 -37
  207. package/lib/splitter/src/splitter-panel.js +51 -26
  208. package/lib/splitter/src/splitter.js +233 -158
  209. package/lib/steps/src/steps.js +11 -6
  210. package/lib/style.css +1 -1
  211. package/lib/style.mini.css +1 -1
  212. package/lib/switch/src/switch.js +87 -59
  213. package/lib/table-select/src/table-select.js +234 -155
  214. package/lib/table-transfer/src/table-transfer.js +12 -7
  215. package/lib/tabs/src/tab-pane.js +34 -17
  216. package/lib/tabs/src/tabs.js +365 -232
  217. package/lib/tag/src/tag.js +67 -49
  218. package/lib/text/src/text.js +100 -76
  219. package/lib/text-ellipsis/src/text-ellipsis.js +86 -55
  220. package/lib/textarea/src/textarea.js +127 -97
  221. package/lib/timeline/src/timeline-item.js +3 -2
  222. package/lib/timeline/src/timeline.js +4 -3
  223. package/lib/tip/src/tip.js +58 -34
  224. package/lib/tooltip/src/tooltip.js +116 -76
  225. package/lib/tour/src/tour.js +4 -3
  226. package/lib/transfer/src/transfer.js +44 -27
  227. package/lib/tree/src/tree.js +717 -500
  228. package/lib/tree-select/src/tree-select.js +351 -256
  229. package/lib/ui/index.js +46 -4
  230. package/lib/ui/src/dom.js +9 -6
  231. package/lib/ui/src/log.js +1 -1
  232. package/lib/upload/src/upload.js +708 -492
  233. package/lib/vxe-icon/style/style.css +1 -1
  234. package/lib/vxe-icon/style/style.mini.css +1 -1
  235. package/lib/watermark/src/util.js +15 -12
  236. package/lib/watermark/src/watermark.js +60 -30
  237. package/package.json +10 -4
  238. package/packages/alert/index.ts +16 -16
  239. package/packages/alert/src/alert.ts +148 -126
  240. package/packages/anchor/index.ts +16 -16
  241. package/packages/anchor/src/anchor-link.ts +139 -121
  242. package/packages/anchor/src/anchor.ts +266 -237
  243. package/packages/anchor/src/util.ts +23 -23
  244. package/packages/anchor-link/index.ts +16 -16
  245. package/packages/avatar/index.ts +16 -16
  246. package/packages/avatar/src/avatar.ts +166 -149
  247. package/packages/backtop/index.ts +16 -16
  248. package/packages/backtop/src/backtop.ts +337 -313
  249. package/packages/badge/index.ts +16 -16
  250. package/packages/badge/src/badge.ts +131 -118
  251. package/packages/breadcrumb/index.ts +16 -16
  252. package/packages/breadcrumb/src/breadcrumb-item.ts +129 -106
  253. package/packages/breadcrumb/src/breadcrumb.ts +94 -92
  254. package/packages/breadcrumb-item/index.ts +16 -16
  255. package/packages/button/index.ts +16 -16
  256. package/packages/button/src/button-group.ts +116 -110
  257. package/packages/button/src/button.ts +975 -855
  258. package/packages/button-group/index.ts +16 -16
  259. package/packages/calendar/index.ts +16 -16
  260. package/packages/calendar/src/calendar.ts +1566 -1352
  261. package/packages/card/index.ts +16 -16
  262. package/packages/card/src/card.ts +285 -236
  263. package/packages/carousel/index.ts +16 -16
  264. package/packages/carousel/src/carousel-item.ts +120 -102
  265. package/packages/carousel/src/carousel.ts +475 -414
  266. package/packages/carousel/src/util.ts +21 -21
  267. package/packages/carousel-item/index.ts +16 -16
  268. package/packages/cascader/index.ts +16 -16
  269. package/packages/cascader/src/cascader.ts +2074 -1896
  270. package/packages/cascader/src/util.ts +9 -9
  271. package/packages/checkbox/index.ts +16 -16
  272. package/packages/checkbox/src/button.ts +267 -221
  273. package/packages/checkbox/src/checkbox.ts +219 -199
  274. package/packages/checkbox/src/group.ts +292 -269
  275. package/packages/checkbox-button/index.ts +16 -16
  276. package/packages/checkbox-group/index.ts +16 -16
  277. package/packages/col/index.ts +16 -16
  278. package/packages/collapse/index.ts +16 -16
  279. package/packages/collapse/src/collapse-pane.ts +142 -114
  280. package/packages/collapse/src/collapse.ts +453 -384
  281. package/packages/collapse/src/util.ts +21 -21
  282. package/packages/collapse-pane/index.ts +16 -16
  283. package/packages/color-picker/index.ts +31 -31
  284. package/packages/color-picker/src/color-picker.ts +1310 -1147
  285. package/packages/color-picker/src/util.ts +436 -423
  286. package/packages/components.ts +350 -349
  287. package/packages/context-menu/index.ts +54 -54
  288. package/packages/context-menu/src/context-menu.ts +773 -681
  289. package/packages/countdown/index.ts +16 -16
  290. package/packages/countdown/src/countdown.ts +295 -262
  291. package/packages/date-panel/index.ts +16 -16
  292. package/packages/date-panel/src/date-panel.ts +2214 -1900
  293. package/packages/date-panel/src/util.ts +354 -326
  294. package/packages/date-picker/index.ts +16 -16
  295. package/packages/date-picker/src/date-picker.ts +1884 -1752
  296. package/packages/date-range-picker/index.ts +16 -16
  297. package/packages/date-range-picker/src/date-range-picker.ts +1728 -1604
  298. package/packages/divider/index.ts +16 -16
  299. package/packages/divider/src/divider.ts +105 -93
  300. package/packages/drawer/index.ts +78 -78
  301. package/packages/drawer/src/drawer.ts +920 -802
  302. package/packages/drawer/src/store.ts +3 -3
  303. package/packages/dynamics/index.ts +124 -117
  304. package/packages/empty/index.ts +16 -16
  305. package/packages/empty/src/empty.ts +124 -103
  306. package/packages/form/index.ts +16 -16
  307. package/packages/form/render/index.ts +646 -614
  308. package/packages/form/src/form-config-item.ts +85 -80
  309. package/packages/form/src/form-group.ts +96 -86
  310. package/packages/form/src/form-item.ts +181 -174
  311. package/packages/form/src/form.ts +1122 -1069
  312. package/packages/form/src/itemInfo.ts +84 -82
  313. package/packages/form/src/render.ts +470 -387
  314. package/packages/form/src/util.ts +98 -93
  315. package/packages/form-gather/index.ts +26 -26
  316. package/packages/form-group/index.ts +16 -16
  317. package/packages/form-item/index.ts +16 -16
  318. package/packages/icon/index.ts +16 -16
  319. package/packages/icon/src/icon.ts +78 -75
  320. package/packages/icon-picker/index.ts +16 -16
  321. package/packages/icon-picker/src/icon-picker.ts +922 -809
  322. package/packages/image/index.ts +16 -16
  323. package/packages/image/src/group.ts +159 -153
  324. package/packages/image/src/image.ts +298 -298
  325. package/packages/image/src/preview.ts +749 -672
  326. package/packages/image/src/util.ts +62 -59
  327. package/packages/image-group/index.ts +16 -16
  328. package/packages/image-preview/index.ts +19 -19
  329. package/packages/index.ts +20 -21
  330. package/packages/input/index.ts +16 -16
  331. package/packages/input/src/input.ts +3201 -2863
  332. package/packages/language/fr-FR.ts +15 -15
  333. package/packages/language/it-IT.ts +4 -4
  334. package/packages/language/uk-UA.ts +1 -1
  335. package/packages/language/uz-UZ.ts +13 -13
  336. package/packages/language/zh-CN.ts +907 -907
  337. package/packages/layout-aside/index.ts +16 -16
  338. package/packages/layout-aside/src/layout-aside.ts +172 -156
  339. package/packages/layout-body/index.ts +16 -16
  340. package/packages/layout-body/src/layout-body.ts +191 -181
  341. package/packages/layout-container/index.ts +16 -16
  342. package/packages/layout-container/src/layout-container.ts +108 -92
  343. package/packages/layout-footer/index.ts +16 -16
  344. package/packages/layout-footer/src/layout-footer.ts +81 -74
  345. package/packages/layout-header/index.ts +16 -16
  346. package/packages/layout-header/src/layout-header.ts +79 -73
  347. package/packages/link/index.ts +16 -16
  348. package/packages/link/src/link.ts +180 -161
  349. package/packages/list/index.ts +16 -16
  350. package/packages/list/src/list.ts +2690 -2564
  351. package/packages/list/src/store.ts +10 -10
  352. package/packages/list/src/util.ts +10 -11
  353. package/packages/loading/index.ts +39 -36
  354. package/packages/loading/src/loading.ts +179 -152
  355. package/packages/mention/index.ts +16 -16
  356. package/packages/mention/src/mention.ts +69 -71
  357. package/packages/menu/index.ts +16 -16
  358. package/packages/menu/src/menu.ts +1000 -857
  359. package/packages/modal/index.ts +164 -141
  360. package/packages/modal/src/modal.ts +1803 -1681
  361. package/packages/modal/src/store.ts +3 -3
  362. package/packages/notice-bar/index.ts +16 -16
  363. package/packages/notice-bar/src/notice-bar.ts +207 -181
  364. package/packages/number-input/index.ts +16 -16
  365. package/packages/number-input/src/number-input.ts +1322 -1242
  366. package/packages/number-input/src/util.ts +25 -25
  367. package/packages/optgroup/index.ts +16 -16
  368. package/packages/option/index.ts +16 -16
  369. package/packages/pager/index.ts +16 -16
  370. package/packages/pager/src/pager.ts +919 -775
  371. package/packages/password-input/index.ts +16 -16
  372. package/packages/password-input/src/password-input.ts +523 -482
  373. package/packages/print/index.ts +18 -18
  374. package/packages/print/src/page-break.ts +104 -92
  375. package/packages/print/src/print.ts +366 -281
  376. package/packages/print/src/util.ts +299 -304
  377. package/packages/print-page-break/index.ts +16 -16
  378. package/packages/pulldown/index.ts +16 -16
  379. package/packages/pulldown/src/pulldown.ts +505 -445
  380. package/packages/radio/index.ts +16 -16
  381. package/packages/radio/src/button.ts +290 -243
  382. package/packages/radio/src/group.ts +275 -252
  383. package/packages/radio/src/radio.ts +237 -218
  384. package/packages/radio-button/index.ts +16 -16
  385. package/packages/radio-group/index.ts +16 -16
  386. package/packages/rate/index.ts +16 -16
  387. package/packages/rate/src/rate.ts +203 -192
  388. package/packages/result/index.ts +16 -16
  389. package/packages/result/src/result.ts +141 -112
  390. package/packages/row/index.ts +16 -16
  391. package/packages/row/src/col.ts +171 -159
  392. package/packages/row/src/row.ts +143 -138
  393. package/packages/scrollbar/index.ts +16 -16
  394. package/packages/scrollbar/src/scrollbar.ts +626 -595
  395. package/packages/segmented/index.ts +16 -16
  396. package/packages/segmented/src/segmented.ts +297 -264
  397. package/packages/select/index.ts +16 -16
  398. package/packages/select/src/optgroup.ts +53 -49
  399. package/packages/select/src/option-info.ts +20 -20
  400. package/packages/select/src/option.ts +47 -47
  401. package/packages/select/src/select.ts +2390 -2214
  402. package/packages/select/src/util.ts +50 -47
  403. package/packages/slider/index.ts +16 -16
  404. package/packages/slider/src/slider.ts +547 -506
  405. package/packages/space/index.ts +16 -16
  406. package/packages/space/src/space.ts +225 -209
  407. package/packages/split/index.ts +16 -16
  408. package/packages/split-pane/index.ts +17 -17
  409. package/packages/splitter/index.ts +16 -16
  410. package/packages/splitter/src/splitter-panel.ts +199 -163
  411. package/packages/splitter/src/splitter.ts +1110 -1020
  412. package/packages/splitter/src/util.ts +21 -21
  413. package/packages/splitter-panel/index.ts +16 -16
  414. package/packages/steps/index.ts +16 -16
  415. package/packages/steps/src/steps.ts +69 -68
  416. package/packages/switch/index.ts +16 -16
  417. package/packages/switch/src/switch.ts +300 -271
  418. package/packages/tab-pane/index.ts +16 -16
  419. package/packages/table-select/index.ts +16 -16
  420. package/packages/table-select/src/table-select.ts +1103 -999
  421. package/packages/table-transfer/index.ts +16 -16
  422. package/packages/table-transfer/src/table-transfer.ts +104 -91
  423. package/packages/tabs/index.ts +16 -16
  424. package/packages/tabs/src/tab-pane.ts +132 -117
  425. package/packages/tabs/src/tabs.ts +1137 -997
  426. package/packages/tabs/src/util.ts +21 -21
  427. package/packages/tag/index.ts +16 -16
  428. package/packages/tag/src/tag.ts +204 -187
  429. package/packages/text/index.ts +16 -16
  430. package/packages/text/src/text.ts +282 -260
  431. package/packages/text-ellipsis/index.ts +16 -16
  432. package/packages/text-ellipsis/src/text-ellipsis.ts +312 -282
  433. package/packages/textarea/index.ts +16 -16
  434. package/packages/textarea/src/textarea.ts +526 -495
  435. package/packages/timeline/index.ts +16 -16
  436. package/packages/timeline/src/timeline-item.ts +65 -67
  437. package/packages/timeline/src/timeline.ts +70 -71
  438. package/packages/timeline-item/index.ts +16 -16
  439. package/packages/tip/index.ts +19 -19
  440. package/packages/tip/src/tip.ts +150 -129
  441. package/packages/tooltip/index.ts +72 -72
  442. package/packages/tooltip/src/tooltip.ts +669 -627
  443. package/packages/tour/index.ts +16 -16
  444. package/packages/tour/src/tour.ts +70 -71
  445. package/packages/transfer/index.ts +16 -16
  446. package/packages/transfer/src/transfer.ts +130 -117
  447. package/packages/tree/index.ts +16 -16
  448. package/packages/tree/src/store.ts +10 -10
  449. package/packages/tree/src/tree.ts +4077 -3852
  450. package/packages/tree/src/util.ts +51 -51
  451. package/packages/tree-select/index.ts +16 -16
  452. package/packages/tree-select/src/tree-select.ts +1217 -1094
  453. package/packages/ui/index.ts +836 -793
  454. package/packages/ui/src/anime.ts +51 -52
  455. package/packages/ui/src/comp.ts +3 -3
  456. package/packages/ui/src/dom.ts +357 -354
  457. package/packages/ui/src/log.ts +19 -19
  458. package/packages/ui/src/utils.ts +79 -79
  459. package/packages/ui/src/vn.ts +39 -39
  460. package/packages/upload/index.ts +20 -20
  461. package/packages/upload/src/upload.ts +2271 -2021
  462. package/packages/upload/src/util.ts +109 -109
  463. package/packages/watermark/index.ts +33 -33
  464. package/packages/watermark/src/util.ts +186 -180
  465. package/packages/watermark/src/watermark.ts +196 -168
  466. package/types/all.d.ts +552 -552
  467. package/types/components/alert.d.ts +83 -87
  468. package/types/components/anchor-link.d.ts +88 -91
  469. package/types/components/anchor.d.ts +97 -104
  470. package/types/components/avatar.d.ts +85 -88
  471. package/types/components/backtop.d.ts +119 -122
  472. package/types/components/badge.d.ts +77 -80
  473. package/types/components/breadcrumb-item.d.ts +77 -80
  474. package/types/components/breadcrumb.d.ts +83 -87
  475. package/types/components/button-group.d.ts +118 -120
  476. package/types/components/button.d.ts +331 -339
  477. package/types/components/calendar.d.ts +247 -264
  478. package/types/components/card.d.ts +111 -113
  479. package/types/components/carousel-item.d.ts +73 -75
  480. package/types/components/carousel.d.ts +130 -134
  481. package/types/components/cascader.d.ts +336 -386
  482. package/types/components/checkbox-button.d.ts +109 -114
  483. package/types/components/checkbox-group.d.ts +152 -154
  484. package/types/components/checkbox.d.ts +123 -128
  485. package/types/components/col.d.ts +77 -80
  486. package/types/components/colgroup.d.ts +64 -69
  487. package/types/components/collapse-pane.d.ts +86 -89
  488. package/types/components/collapse.d.ts +123 -133
  489. package/types/components/color-picker.d.ts +275 -280
  490. package/types/components/column.d.ts +834 -851
  491. package/types/components/context-menu.d.ts +282 -289
  492. package/types/components/countdown.d.ts +108 -112
  493. package/types/components/date-panel.d.ts +319 -331
  494. package/types/components/date-picker.d.ts +361 -384
  495. package/types/components/date-range-picker.d.ts +351 -371
  496. package/types/components/divider.d.ts +72 -75
  497. package/types/components/drawer.d.ts +333 -344
  498. package/types/components/empty.d.ts +75 -78
  499. package/types/components/flow-design.d.ts +73 -85
  500. package/types/components/flow-view.d.ts +73 -85
  501. package/types/components/form-design.d.ts +370 -376
  502. package/types/components/form-gather.d.ts +120 -124
  503. package/types/components/form-group.d.ts +73 -77
  504. package/types/components/form-item.d.ts +395 -413
  505. package/types/components/form-view.d.ts +179 -183
  506. package/types/components/form.d.ts +499 -495
  507. package/types/components/gantt-module/gantt-view.d.ts +195 -200
  508. package/types/components/gantt-module/index.d.ts +1 -1
  509. package/types/components/gantt-plugins/extend-gantt-chart.d.ts +137 -131
  510. package/types/components/gantt-plugins/index.d.ts +1 -1
  511. package/types/components/gantt.d.ts +1248 -1399
  512. package/types/components/grid.d.ts +1289 -1317
  513. package/types/components/icon-picker.d.ts +242 -253
  514. package/types/components/icon.d.ts +332 -87
  515. package/types/components/image-group.d.ts +124 -127
  516. package/types/components/image-preview.d.ts +167 -167
  517. package/types/components/image.d.ts +166 -173
  518. package/types/components/input.d.ts +429 -453
  519. package/types/components/layout-aside.d.ts +123 -123
  520. package/types/components/layout-body.d.ts +110 -113
  521. package/types/components/layout-container.d.ts +73 -75
  522. package/types/components/layout-footer.d.ts +71 -73
  523. package/types/components/layout-header.d.ts +67 -69
  524. package/types/components/link.d.ts +107 -111
  525. package/types/components/list-design.d.ts +189 -190
  526. package/types/components/list-view.d.ts +193 -199
  527. package/types/components/list.d.ts +678 -715
  528. package/types/components/loading.d.ts +98 -103
  529. package/types/components/mention.d.ts +70 -77
  530. package/types/components/menu.d.ts +284 -295
  531. package/types/components/modal.d.ts +567 -584
  532. package/types/components/notice-bar.d.ts +102 -106
  533. package/types/components/number-input.d.ts +359 -365
  534. package/types/components/optgroup.d.ts +85 -88
  535. package/types/components/option.d.ts +94 -103
  536. package/types/components/pager.d.ts +330 -335
  537. package/types/components/password-input.d.ts +143 -156
  538. package/types/components/print-page-break.d.ts +65 -69
  539. package/types/components/print.d.ts +243 -245
  540. package/types/components/pulldown.d.ts +231 -239
  541. package/types/components/radio-button.d.ts +113 -118
  542. package/types/components/radio-group.d.ts +151 -153
  543. package/types/components/radio.d.ts +129 -134
  544. package/types/components/rate.d.ts +83 -88
  545. package/types/components/result.d.ts +81 -84
  546. package/types/components/row.d.ts +77 -81
  547. package/types/components/scrollbar.d.ts +299 -305
  548. package/types/components/segmented.d.ts +119 -123
  549. package/types/components/select.d.ts +598 -616
  550. package/types/components/slider.d.ts +137 -151
  551. package/types/components/space.d.ts +120 -127
  552. package/types/components/split-pane.d.ts +126 -133
  553. package/types/components/split.d.ts +301 -312
  554. package/types/components/splitter-panel.d.ts +123 -130
  555. package/types/components/splitter.d.ts +290 -301
  556. package/types/components/steps.d.ts +63 -68
  557. package/types/components/switch.d.ts +127 -133
  558. package/types/components/tab-pane.d.ts +111 -114
  559. package/types/components/table-module/custom.d.ts +123 -123
  560. package/types/components/table-module/edit.d.ts +297 -276
  561. package/types/components/table-module/export.d.ts +88 -96
  562. package/types/components/table-module/filter.d.ts +144 -144
  563. package/types/components/table-module/index.d.ts +7 -7
  564. package/types/components/table-module/keyboard.d.ts +26 -26
  565. package/types/components/table-module/menu.d.ts +46 -46
  566. package/types/components/table-module/validator.d.ts +53 -53
  567. package/types/components/table-plugins/extend-cell-area.d.ts +781 -781
  568. package/types/components/table-plugins/extend-pivot-table.d.ts +59 -58
  569. package/types/components/table-plugins/filters-combination.d.ts +15 -15
  570. package/types/components/table-plugins/filters-complex-input.d.ts +9 -9
  571. package/types/components/table-plugins/index.d.ts +4 -4
  572. package/types/components/table-select.d.ts +268 -276
  573. package/types/components/table-transfer.d.ts +80 -84
  574. package/types/components/table.d.ts +7530 -8000
  575. package/types/components/tabs.d.ts +314 -352
  576. package/types/components/tag.d.ts +108 -114
  577. package/types/components/text-ellipsis.d.ts +107 -112
  578. package/types/components/text.d.ts +112 -122
  579. package/types/components/textarea.d.ts +261 -275
  580. package/types/components/timeline-item.d.ts +66 -75
  581. package/types/components/timeline.d.ts +70 -77
  582. package/types/components/tip.d.ts +81 -83
  583. package/types/components/toolbar.d.ts +327 -336
  584. package/types/components/tooltip.d.ts +250 -255
  585. package/types/components/tour.d.ts +70 -77
  586. package/types/components/transfer.d.ts +80 -84
  587. package/types/components/tree-select.d.ts +361 -376
  588. package/types/components/tree.d.ts +994 -1036
  589. package/types/components/upload.d.ts +477 -518
  590. package/types/components/watermark.d.ts +116 -120
  591. package/types/handles/form-design.d.ts +50 -50
  592. package/types/handles/index.d.ts +3 -3
  593. package/types/handles/list-design.d.ts +1 -2
  594. package/types/handles/table.d.ts +15 -15
  595. package/types/index.d.ts +8 -8
  596. package/types/ui/commands.d.ts +57 -57
  597. package/types/ui/formats.d.ts +62 -62
  598. package/types/ui/global-config.d.ts +269 -269
  599. package/types/ui/global-icon.d.ts +315 -315
  600. package/types/ui/hooks.d.ts +13 -13
  601. package/types/ui/index.d.ts +100 -100
  602. package/types/ui/interceptor.d.ts +52 -52
  603. package/types/ui/menus.d.ts +89 -89
  604. package/types/ui/renderer.d.ts +1033 -1047
  605. package/types/ui/validators.d.ts +37 -38
  606. /package/dist/{iconfont.1792992046297.ttf → iconfont.1793007755017.ttf} +0 -0
  607. /package/dist/{iconfont.1792992046297.woff → iconfont.1793007755017.woff} +0 -0
  608. /package/dist/{iconfont.1792992046297.woff2 → iconfont.1793007755017.woff2} +0 -0
  609. /package/es/icon/{iconfont.1792992046297.ttf → iconfont.1793007755017.ttf} +0 -0
  610. /package/es/icon/{iconfont.1792992046297.woff → iconfont.1793007755017.woff} +0 -0
  611. /package/es/icon/{iconfont.1792992046297.woff2 → iconfont.1793007755017.woff2} +0 -0
  612. /package/es/{iconfont.1792992046297.ttf → iconfont.1793007755017.ttf} +0 -0
  613. /package/es/{iconfont.1792992046297.woff → iconfont.1793007755017.woff} +0 -0
  614. /package/es/{iconfont.1792992046297.woff2 → iconfont.1793007755017.woff2} +0 -0
  615. /package/es/vxe-icon/{iconfont.1792992046297.ttf → iconfont.1793007755017.ttf} +0 -0
  616. /package/es/vxe-icon/{iconfont.1792992046297.woff → iconfont.1793007755017.woff} +0 -0
  617. /package/es/vxe-icon/{iconfont.1792992046297.woff2 → iconfont.1793007755017.woff2} +0 -0
  618. /package/lib/icon/style/{iconfont.1792992046297.ttf → iconfont.1793007755017.ttf} +0 -0
  619. /package/lib/icon/style/{iconfont.1792992046297.woff → iconfont.1793007755017.woff} +0 -0
  620. /package/lib/icon/style/{iconfont.1792992046297.woff2 → iconfont.1793007755017.woff2} +0 -0
  621. /package/lib/{iconfont.1792992046297.ttf → iconfont.1793007755017.ttf} +0 -0
  622. /package/lib/{iconfont.1792992046297.woff → iconfont.1793007755017.woff} +0 -0
  623. /package/lib/{iconfont.1792992046297.woff2 → iconfont.1793007755017.woff2} +0 -0
  624. /package/lib/vxe-icon/style/{iconfont.1792992046297.ttf → iconfont.1793007755017.ttf} +0 -0
  625. /package/lib/vxe-icon/style/{iconfont.1792992046297.woff → iconfont.1793007755017.woff} +0 -0
  626. /package/lib/vxe-icon/style/{iconfont.1792992046297.woff2 → iconfont.1793007755017.woff2} +0 -0
@@ -1,1069 +1,1122 @@
1
- import { h, ref, Ref, provide, computed, inject, reactive, watch, nextTick, PropType, onMounted, onUnmounted } from 'vue'
2
- import { defineVxeComponent } from '../../ui/src/comp'
3
- import XEUtils from 'xe-utils'
4
- import { VxeUI } from '../../ui'
5
- import { eqEmptyValue, getFuncText, isEnableConf } from '../../ui/src/utils'
6
- import { scrollToView } from '../../ui/src/dom'
7
- import { createItem, handleFieldOrItem, isHiddenItem, isActiveItem } from './util'
8
- import VxeTooltipComponent from '../../tooltip'
9
- import VxeFormConfigItem from './form-config-item'
10
- import VxeLoadingComponent from '../../loading'
11
- import { getSlotVNs } from '../../ui/src/vn'
12
- import { createComponentLog } from '../../ui/src/log'
13
-
14
- import '../render'
15
-
16
- import type { VxeFormConstructor, VxeFormPropTypes, VxeFormEmits, FormReactData, FormMethods, FormPrivateRef, VxeFormPrivateMethods, VxeFormDefines, VxeFormItemPropTypes, VxeTooltipInstance, FormInternalData, VxeFormPrivateComputed, ValueOf } from '../../../types'
17
- import type { VxeGridConstructor, VxeGridPrivateMethods } from '../../../types/components/grid'
18
-
19
- const { getConfig, validators, renderer, createEvent, useFns, globalEvents } = VxeUI
20
-
21
- const { warnLog, errLog } = createComponentLog('form')
22
-
23
- class Rule {
24
- constructor (rule: any) {
25
- Object.assign(this, {
26
- $options: rule,
27
- required: rule.required,
28
- min: rule.min,
29
- max: rule.min,
30
- type: rule.type,
31
- pattern: rule.pattern,
32
- validator: rule.validator,
33
- trigger: rule.trigger,
34
- maxWidth: rule.maxWidth
35
- })
36
- }
37
-
38
- get content () {
39
- return getFuncText(this.$options.content || this.$options.message)
40
- }
41
-
42
- get message () {
43
- return this.content
44
- }
45
-
46
- [key: string]: any
47
- }
48
-
49
- // 如果存在 pattern,判断正则
50
- function validREValue (pattern: string | RegExp | undefined, val: string) {
51
- if (pattern && !(XEUtils.isRegExp(pattern) ? pattern : new RegExp(pattern)).test(val)) {
52
- return false
53
- }
54
- return true
55
- }
56
-
57
- // 如果存在 max,判断最大值
58
- function validMaxValue (max: string | number | undefined, num: number) {
59
- if (!XEUtils.eqNull(max) && num > XEUtils.toNumber(max)) {
60
- return false
61
- }
62
- return true
63
- }
64
-
65
- // 如果存在 min,判断最小值
66
- function validMinValue (min: string | number | undefined, num: number) {
67
- if (!XEUtils.eqNull(min) && num < XEUtils.toNumber(min)) {
68
- return false
69
- }
70
- return true
71
- }
72
-
73
- function validRuleValue (rule: VxeFormDefines.FormRule, val: any, required: boolean | undefined) {
74
- const { type, min, max, pattern } = rule
75
- const isArrType = type === 'array'
76
- const isNumType = type === 'number'
77
- const isStrType = type === 'string'
78
- const strVal = `${val}`
79
- if (!validREValue(pattern, strVal)) {
80
- return false
81
- }
82
- if (isArrType) {
83
- if (!XEUtils.isArray(val)) {
84
- return false
85
- }
86
- if (required) {
87
- if (!val.length) {
88
- return false
89
- }
90
- }
91
- if (!validMinValue(min, val.length)) {
92
- return false
93
- }
94
- if (!validMaxValue(max, val.length)) {
95
- return false
96
- }
97
- } else if (isNumType) {
98
- const numVal = Number(val)
99
- if (isNaN(numVal)) {
100
- return false
101
- }
102
- if (!validMinValue(min, numVal)) {
103
- return false
104
- }
105
- if (!validMaxValue(max, numVal)) {
106
- return false
107
- }
108
- } else {
109
- if (isStrType) {
110
- if (!XEUtils.isString(val)) {
111
- return false
112
- }
113
- }
114
- if (required) {
115
- if (!strVal) {
116
- return false
117
- }
118
- }
119
- if (!validMinValue(min, strVal.length)) {
120
- return false
121
- }
122
- if (!validMaxValue(max, strVal.length)) {
123
- return false
124
- }
125
- }
126
- return true
127
- }
128
-
129
- function checkRuleStatus (rule: VxeFormDefines.FormRule, data: any, val: any) {
130
- const { required, field } = rule
131
- const currVal = field ? XEUtils.get(data, field) : val
132
- const isEmptyVal = XEUtils.isArray(currVal) ? !currVal.length : eqEmptyValue(currVal)
133
- if (required) {
134
- if (isEmptyVal) {
135
- return false
136
- }
137
- if (!validRuleValue(rule, currVal, required)) {
138
- return false
139
- }
140
- } else {
141
- if (!isEmptyVal) {
142
- if (!validRuleValue(rule, currVal, required)) {
143
- return false
144
- }
145
- }
146
- }
147
- return true
148
- }
149
-
150
- export function createReactData (): FormReactData {
151
- return {
152
- collapseAll: false,
153
- staticItems: [],
154
- formItems: [],
155
- itemWidth: 0
156
- }
157
- }
158
-
159
- function createInternalData (): FormInternalData {
160
- return {
161
- meTimeout: undefined,
162
- stTimeout: undefined,
163
- tooltipStore: {
164
- item: null,
165
- visible: false
166
- },
167
- itemFormatCache: {},
168
- fullItemList: [],
169
- fullItemIdData: {},
170
- fullItemFieldData: {}
171
- }
172
- }
173
-
174
- export default defineVxeComponent({
175
- name: 'VxeForm',
176
- props: {
177
- collapseStatus: {
178
- type: Boolean as PropType<VxeFormPropTypes.CollapseStatus>,
179
- default: true
180
- },
181
- loading: Boolean as PropType<VxeFormPropTypes.Loading>,
182
- data: Object as PropType<VxeFormPropTypes.Data>,
183
- size: {
184
- type: String as PropType<VxeFormPropTypes.Size>,
185
- default: () => getConfig().form.size || getConfig().size
186
- },
187
- span: {
188
- type: [String, Number] as PropType<VxeFormPropTypes.Span>,
189
- default: () => getConfig().form.span
190
- },
191
- align: {
192
- type: String as PropType<VxeFormPropTypes.Align>,
193
- default: () => getConfig().form.align
194
- },
195
- verticalAlign: {
196
- type: String as PropType<VxeFormPropTypes.VerticalAlign>,
197
- default: () => getConfig().form.verticalAlign
198
- },
199
- border: {
200
- type: Boolean as PropType<VxeFormPropTypes.Border>,
201
- default: () => getConfig().form.border
202
- },
203
- titleBackground: {
204
- type: Boolean as PropType<VxeFormPropTypes.TitleBackground>,
205
- default: () => getConfig().form.titleBackground
206
- },
207
- titleBold: {
208
- type: Boolean as PropType<VxeFormPropTypes.TitleBold>,
209
- default: () => getConfig().form.titleBold
210
- },
211
- titleAlign: {
212
- type: String as PropType<VxeFormPropTypes.TitleAlign>,
213
- default: () => getConfig().form.titleAlign
214
- },
215
- titleWidth: {
216
- type: [String, Number] as PropType<VxeFormPropTypes.TitleWidth>,
217
- default: () => getConfig().form.titleWidth
218
- },
219
- titleColon: {
220
- type: Boolean as PropType<VxeFormPropTypes.TitleColon>,
221
- default: () => getConfig().form.titleColon
222
- },
223
- titleAsterisk: {
224
- type: Boolean as PropType<VxeFormPropTypes.TitleAsterisk>,
225
- default: () => getConfig().form.titleAsterisk
226
- },
227
- titleOverflow: {
228
- type: [Boolean, String] as PropType<VxeFormPropTypes.TitleOverflow>,
229
- default: () => getConfig().form.titleOverflow
230
- },
231
- vertical: {
232
- type: Boolean as PropType<VxeFormPropTypes.Vertical>,
233
- default: () => getConfig().form.vertical
234
- },
235
- padding: {
236
- type: Boolean as PropType<VxeFormPropTypes.Padding>,
237
- default: () => getConfig().form.padding
238
- },
239
- className: [String, Function] as PropType<VxeFormPropTypes.ClassName>,
240
- readonly: Boolean as PropType<VxeFormPropTypes.Readonly>,
241
- disabled: Boolean as PropType<VxeFormPropTypes.Disabled>,
242
- items: Array as PropType<VxeFormPropTypes.Items>,
243
- rules: Object as PropType<VxeFormPropTypes.Rules>,
244
- preventSubmit: {
245
- type: Boolean as PropType<VxeFormPropTypes.PreventSubmit>,
246
- default: () => getConfig().form.preventSubmit
247
- },
248
- validConfig: Object as PropType<VxeFormPropTypes.ValidConfig>,
249
- tooltipConfig: Object as PropType<VxeFormPropTypes.TooltipConfig>,
250
- collapseConfig: Object as PropType<VxeFormPropTypes.CollapseConfig>,
251
- customLayout: {
252
- type: Boolean as PropType<VxeFormPropTypes.CustomLayout>,
253
- default: () => getConfig().form.customLayout
254
- },
255
- params: Object as PropType<VxeFormPropTypes.Params>
256
- },
257
- emits: [
258
- 'update:collapseStatus',
259
- 'collapse',
260
- 'toggle-collapse',
261
- 'submit',
262
- 'submit-invalid',
263
- 'reset'
264
- ] as VxeFormEmits,
265
- setup (props, context) {
266
- const { slots, emit } = context
267
-
268
- const $xeGrid = inject<(VxeGridConstructor & VxeGridPrivateMethods) | null>('$xeGrid', null)
269
-
270
- const xID = XEUtils.uniqueId()
271
-
272
- const { computeSize } = useFns.useSize(props)
273
-
274
- const reactData = reactive(createReactData())
275
-
276
- const internalData = createInternalData()
277
-
278
- const refElem = ref<HTMLFormElement>()
279
- const refTooltip = ref() as Ref<VxeTooltipInstance>
280
-
281
- const computeValidOpts = computed(() => {
282
- return Object.assign({}, getConfig().form.validConfig, props.validConfig)
283
- })
284
-
285
- const computeTooltipOpts = computed(() => {
286
- return Object.assign({}, getConfig().tooltip, getConfig().form.tooltipConfig, props.tooltipConfig)
287
- })
288
-
289
- const computeCollapseOpts = computed(() => {
290
- return Object.assign({}, getConfig().form.collapseConfig, props.collapseConfig)
291
- })
292
-
293
- const computeAutoItemWidthList = computed(() => {
294
- const { titleWidth: allTitleWidth, vertical: allVertical } = props
295
- const { formItems } = reactData
296
- const itemList: VxeFormDefines.ItemInfo[] = []
297
- XEUtils.eachTree(formItems, (item) => {
298
- const { titleWidth, vertical } = item
299
- if (titleWidth === 'auto') {
300
- itemList.push(item)
301
- } else {
302
- const itemVertical = XEUtils.eqNull(vertical) ? allVertical : vertical
303
- const itemTitleWidth = itemVertical ? null : (XEUtils.eqNull(titleWidth) ? allTitleWidth : titleWidth)
304
- if (itemTitleWidth === 'auto' && (!item.children || !item.children.length)) {
305
- itemList.push(item)
306
- }
307
- }
308
- }, { children: 'children' })
309
- return itemList
310
- })
311
-
312
- const refMaps: FormPrivateRef = {
313
- refElem
314
- }
315
-
316
- const computeMaps: VxeFormPrivateComputed = {
317
- computeSize,
318
- computeValidOpts,
319
- computeTooltipOpts,
320
- computeCollapseOpts,
321
- computeAutoItemWidthList
322
- }
323
-
324
- const $xeForm = {
325
- xID,
326
- props,
327
- context,
328
- reactData,
329
- internalData,
330
-
331
- xeGrid: $xeGrid,
332
- getRefMaps: () => refMaps,
333
- getComputeMaps: () => computeMaps
334
- } as unknown as VxeFormConstructor & VxeFormPrivateMethods
335
-
336
- const dispatchEvent = (type: ValueOf<VxeFormEmits>, params: Record<string, any>, evnt: Event | null) => {
337
- emit(type, createEvent(evnt, { $form: $xeForm, $grid: $xeGrid }, params))
338
- }
339
-
340
- const callSlot = (slotFunc: ((params: any) => any) | string | null, params: any) => {
341
- if (slotFunc) {
342
- if (XEUtils.isString(slotFunc)) {
343
- slotFunc = slots[slotFunc] || null
344
- }
345
- if (XEUtils.isFunction(slotFunc)) {
346
- return getSlotVNs(slotFunc(params))
347
- }
348
- }
349
- return []
350
- }
351
-
352
- const loadItems = (list: VxeFormPropTypes.Items) => {
353
- if (list.length) {
354
- list.forEach((item) => {
355
- if (item.slots) {
356
- XEUtils.each(item.slots, (func) => {
357
- if (func && !XEUtils.isFunction(func)) {
358
- if (!slots[func]) {
359
- errLog('vxe.error.notSlot', [func])
360
- }
361
- }
362
- })
363
- }
364
- })
365
- }
366
- reactData.staticItems = XEUtils.mapTree(list, item => createItem($xeForm, item), { children: 'children' })
367
- internalData.itemFormatCache = {}
368
- return nextTick().then(() => {
369
- return recalculate()
370
- })
371
- }
372
-
373
- /**
374
- * 已废弃,被 getFormFlatItems 替换
375
- * @deprecated
376
- */
377
- const getItems = () => {
378
- // errLog('vxe.error.delFunc', ['getItems', 'getFlatItems'])
379
- return getFlatItems()
380
- }
381
-
382
- const getFlatItems = () => {
383
- return internalData.fullItemList
384
- }
385
-
386
- const getNestedItems = () => {
387
- return reactData.formItems
388
- }
389
-
390
- const getItemByField = (field: string) => {
391
- const { fullItemFieldData } = internalData
392
- const itemRest = fullItemFieldData[field]
393
- return itemRest ? itemRest.item : null
394
- }
395
-
396
- const getCollapseStatus = () => {
397
- return reactData.collapseAll
398
- }
399
-
400
- const toggleCollapse = () => {
401
- const status = !getCollapseStatus()
402
- reactData.collapseAll = status
403
- emit('update:collapseStatus', status)
404
- return nextTick()
405
- }
406
-
407
- const toggleCollapseEvent = (evnt: Event) => {
408
- const actionRest = toggleCollapse()
409
- const status = getCollapseStatus()
410
- dispatchEvent('toggle-collapse', { status, collapse: status, data: props.data }, evnt)
411
- dispatchEvent('collapse', { status, collapse: status, data: props.data }, evnt)
412
- actionRest.then(() => {
413
- recalculate().then(() => {
414
- if ($xeGrid) {
415
- $xeGrid.recalculate(true)
416
- }
417
- })
418
- if ($xeGrid) {
419
- $xeGrid.recalculate()
420
- }
421
- })
422
- }
423
-
424
- const clearValidate = (fieldOrItem?: VxeFormItemPropTypes.Field | VxeFormItemPropTypes.Field[] | VxeFormDefines.ItemInfo | VxeFormDefines.ItemInfo[]) => {
425
- const { fullItemList } = internalData
426
- if (fieldOrItem) {
427
- let fields: any = fieldOrItem
428
- if (!XEUtils.isArray(fieldOrItem)) {
429
- fields = [fieldOrItem]
430
- }
431
- fields.forEach((field: any) => {
432
- if (field) {
433
- const item = handleFieldOrItem($xeForm, field)
434
- if (item) {
435
- item.showError = false
436
- item.showIconMsg = false
437
- }
438
- }
439
- })
440
- } else {
441
- fullItemList.forEach((item) => {
442
- item.showError = false
443
- item.showIconMsg = false
444
- })
445
- }
446
- return nextTick()
447
- }
448
-
449
- const getResetValue = (item: VxeFormDefines.ItemInfo, data: any, itemValue: any, currentField?: string) => {
450
- const { field, resetValue } = item
451
- if (XEUtils.isFunction(resetValue)) {
452
- return resetValue({
453
- field,
454
- item,
455
- data,
456
- currentField: currentField || field || '',
457
- currentValue: itemValue,
458
- $form: $xeForm,
459
- $grid: $xeGrid
460
- })
461
- } else if (XEUtils.eqNull(resetValue)) {
462
- // 默认
463
- if (XEUtils.isArray(itemValue)) {
464
- return []
465
- }
466
- }
467
- return resetValue
468
- }
469
-
470
- const cacheItem = () => {
471
- const { formItems } = reactData
472
- const itemIdData: Record<string, VxeFormDefines.ItemCacheItem> = {}
473
- const itemFieldData: Record<string, VxeFormDefines.ItemCacheItem> = {}
474
- const itemList: VxeFormDefines.ItemInfo[] = []
475
- XEUtils.eachTree(formItems, (item, index, items) => {
476
- const { id, field } = item
477
- const itemRest = { item, items, index }
478
- if (id) {
479
- itemIdData[id] = itemRest
480
- }
481
- if (field) {
482
- itemFieldData[field] = itemRest
483
- }
484
- itemList.push(item)
485
- }, { children: 'children' })
486
- internalData.fullItemList = itemList
487
- internalData.fullItemFieldData = itemFieldData
488
- internalData.fullItemIdData = itemIdData
489
- }
490
-
491
- const reset = () => {
492
- const { data } = props
493
- const { fullItemList } = internalData
494
- if (data) {
495
- fullItemList.forEach((item) => {
496
- const { field, itemRender } = item
497
- if (isEnableConf(itemRender)) {
498
- const { name, startField, endField } = itemRender
499
- const compConf = renderer.get(name)
500
- const fiResetMethod = compConf ? (compConf.formItemResetMethod || compConf.itemResetMethod) : null
501
- if (compConf && fiResetMethod) {
502
- fiResetMethod({ data, field, property: field, item, $form: $xeForm, $grid: $xeGrid })
503
- } else if (field) {
504
- const itemValue = XEUtils.get(data, field)
505
- XEUtils.set(data, field, getResetValue(item, data, itemValue))
506
- }
507
- if (startField && endField) {
508
- XEUtils.set(data, startField, getResetValue(item, data, XEUtils.get(data, startField), startField))
509
- XEUtils.set(data, endField, getResetValue(item, data, XEUtils.get(data, endField), endField))
510
- }
511
-
512
- if (field === 'startxxxx') {
513
- return ''
514
- } else if (field === 'endxxx') {
515
- return ''
516
- }
517
- return ''
518
- }
519
- })
520
- }
521
- internalData.itemFormatCache = {}
522
- clearValidate()
523
- return recalculate()
524
- }
525
-
526
- const resetEvent = (evnt: Event) => {
527
- evnt.preventDefault()
528
- reset()
529
- dispatchEvent('reset', { data: props.data }, evnt)
530
- }
531
-
532
- const handleFocus = (fields: string[]) => {
533
- const el = refElem.value
534
- if (el) {
535
- for (let i = 0; i < fields.length; i++) {
536
- const field = fields[i]
537
- const item = getItemByField(field)
538
- if (item && isEnableConf(item.itemRender)) {
539
- const { itemRender } = item
540
- const compConf = renderer.get(itemRender.name)
541
- // 定位到第一个
542
- if (!i) {
543
- scrollToView(el.querySelector(`.${item.id}`))
544
- }
545
- let inputElem: HTMLElement | null = null
546
- const autoFocus = itemRender.autoFocus || itemRender.autofocus || (compConf ? compConf.formItemAutoFocus : null)
547
- // 如果指定了聚焦 class
548
- if (XEUtils.isFunction(autoFocus)) {
549
- inputElem = autoFocus({ $form: $xeForm, $grid: $xeGrid, item, data: props.data, field })
550
- } else {
551
- if (autoFocus === true) {
552
- // 自动匹配模式,会自动匹配第一个可输入元素
553
- inputElem = el.querySelector(`.${item.id} input,textarea`)
554
- } else if (autoFocus) {
555
- inputElem = el.querySelector(`.${item.id} ${autoFocus}`) as HTMLInputElement
556
- }
557
- }
558
- if (inputElem) {
559
- inputElem.focus()
560
- break
561
- }
562
- }
563
- }
564
- }
565
- }
566
-
567
- /**
568
- * 校验数据
569
- * 按表格行、列顺序依次校验(同步或异步)
570
- * 校验规则根据索引顺序依次校验,如果是异步则会等待校验完成才会继续校验下一列
571
- * 如果校验失败则,触发回调或者 Promise<(ErrMap 校验不通过列的信息)>
572
- * 如果是传回调方式这返回一个 (ErrMap 校验不通过列的信息)
573
- *
574
- * rule 配置:
575
- * required=Boolean 是否必填
576
- * min=Number 最小长度
577
- * max=Number 最大长度
578
- * validator=Function({ itemValue, rule, rules, data, property }) 自定义校验,接收一个 Promise
579
- * trigger=change 触发方式
580
- */
581
- const validItemRules = (validType: string, fields: string | string[], val?: any): Promise<VxeFormDefines.ValidateErrorMapParams | undefined> => {
582
- const { data, rules: formRules } = props
583
- const errorMaps: VxeFormDefines.ValidateErrorMapParams = {}
584
- if (!XEUtils.isArray(fields)) {
585
- fields = [fields]
586
- }
587
- return Promise.all(
588
- fields.map((property) => {
589
- const errorRules: Rule[] = []
590
- const syncVailds: Promise<any>[] = []
591
- if (property && formRules) {
592
- const item = getItemByField(property)
593
- const rules = item && item.rules ? item.rules : XEUtils.get(formRules, property)
594
- if (rules) {
595
- const itemValue = XEUtils.isUndefined(val) ? XEUtils.get(data, property) : val
596
- rules.forEach((rule) => {
597
- const { trigger, validator } = rule
598
- if (validType === 'all' || !trigger || validType === trigger) {
599
- if (validator) {
600
- const validParams = {
601
- itemValue,
602
- rule,
603
- rules,
604
- data,
605
- field: property,
606
- property,
607
- $form: $xeForm
608
- }
609
- let customValid: any
610
- if (XEUtils.isString(validator)) {
611
- const gvItem = validators.get(validator)
612
- if (gvItem) {
613
- const validatorMethod = gvItem.formItemValidatorMethod || gvItem.itemValidatorMethod
614
- if (validatorMethod) {
615
- customValid = validatorMethod(validParams)
616
- } else {
617
- warnLog('vxe.error.notValidators', [validator])
618
- }
619
- } else {
620
- errLog('vxe.error.notValidators', [validator])
621
- }
622
- } else {
623
- customValid = validator(validParams)
624
- }
625
- if (customValid) {
626
- if (XEUtils.isError(customValid)) {
627
- errorRules.push(new Rule({ type: 'custom', trigger, content: customValid.message, rule: new Rule(rule) }))
628
- } else if (customValid.catch) {
629
- // 如果为异步校验(注:异步校验是并发无序的)
630
- syncVailds.push(
631
- customValid.catch((e: any) => {
632
- errorRules.push(new Rule({ type: 'custom', trigger, content: e ? e.message : (rule.content || rule.message), rule: new Rule(rule) }))
633
- })
634
- )
635
- }
636
- }
637
- } else {
638
- if (!checkRuleStatus(rule, data, itemValue)) {
639
- errorRules.push(new Rule(rule))
640
- }
641
- }
642
- }
643
- })
644
- }
645
- }
646
- return Promise.all(syncVailds).then(() => {
647
- if (errorRules.length) {
648
- errorMaps[property] = errorRules.map(rule => {
649
- return {
650
- $form: $xeForm,
651
- rule,
652
- data,
653
- field: property,
654
- property
655
- }
656
- })
657
- }
658
- })
659
- })
660
- ).then(() => {
661
- if (!XEUtils.isEmpty(errorMaps)) {
662
- return Promise.reject(errorMaps)
663
- }
664
- })
665
- }
666
-
667
- const beginValidate = (itemList: VxeFormDefines.ItemInfo[], type?: string, callback?: any): Promise<VxeFormDefines.ValidateErrorMapParams | void> => {
668
- const { data, rules: formRules } = props
669
- const validOpts = computeValidOpts.value
670
- const validRest: any = {}
671
- const validFields: string[] = []
672
- const itemValids: any[] = []
673
- clearTimeout(internalData.meTimeout)
674
- if (data && formRules) {
675
- itemList.forEach((item) => {
676
- const { field } = item
677
- if (field && !isHiddenItem($xeForm, item) && isActiveItem($xeForm, item)) {
678
- itemValids.push(
679
- validItemRules(type || 'all', field).then(() => {
680
- item.errRule = null
681
- }).catch((errorMaps: VxeFormDefines.ValidateErrorMapParams) => {
682
- const rest = errorMaps[field]
683
- if (!validRest[field]) {
684
- validRest[field] = []
685
- }
686
- validRest[field].push(rest)
687
- validFields.push(field)
688
- item.errRule = rest[0].rule
689
- return Promise.reject(rest)
690
- })
691
- )
692
- }
693
- })
694
- return Promise.all(itemValids).then(() => {
695
- if (callback) {
696
- callback()
697
- }
698
- }).catch(() => {
699
- return new Promise<void>((resolve) => {
700
- internalData.meTimeout = setTimeout(() => {
701
- itemList.forEach((item) => {
702
- if (item.errRule) {
703
- item.showError = true
704
- }
705
- })
706
- }, 20)
707
- if (validOpts.autoPos !== false) {
708
- nextTick(() => {
709
- handleFocus(validFields)
710
- })
711
- }
712
- if (callback) {
713
- callback(validRest)
714
- resolve()
715
- } else {
716
- resolve(validRest)
717
- }
718
- })
719
- })
720
- }
721
- if (callback) {
722
- callback()
723
- }
724
- return Promise.resolve()
725
- }
726
-
727
- const validate = (callback: any): Promise<any> => {
728
- const { readonly } = props
729
- const { fullItemList } = internalData
730
- clearValidate()
731
- if (readonly) {
732
- return Promise.resolve()
733
- }
734
- return beginValidate(fullItemList, '', callback).then((params) => {
735
- recalculate()
736
- return params
737
- })
738
- }
739
-
740
- const validateField = (fieldOrItem: VxeFormItemPropTypes.Field | VxeFormItemPropTypes.Field[] | VxeFormDefines.ItemInfo | VxeFormDefines.ItemInfo[], callback: any) => {
741
- const { readonly } = props
742
- if (readonly) {
743
- return Promise.resolve()
744
- }
745
- let fields: any[] = []
746
- if (fieldOrItem) {
747
- if (XEUtils.isArray(fieldOrItem)) {
748
- fields = fieldOrItem
749
- } else {
750
- fields = [fieldOrItem]
751
- }
752
- }
753
- const itemList = fields.map(field => handleFieldOrItem($xeForm, field)) as VxeFormDefines.ItemInfo[]
754
- return beginValidate(itemList, '', callback).then((params) => {
755
- recalculate()
756
- return params
757
- })
758
- }
759
-
760
- const handleSubmitEvent = (evnt: Event) => {
761
- const { readonly } = props
762
- const { fullItemList } = internalData
763
- clearValidate()
764
- if (readonly) {
765
- dispatchEvent('submit', { data: props.data }, evnt)
766
- recalculate()
767
- return
768
- }
769
- beginValidate(fullItemList).then((errMap) => {
770
- if (errMap) {
771
- dispatchEvent('submit-invalid', { data: props.data, errMap }, evnt)
772
- } else {
773
- dispatchEvent('submit', { data: props.data }, evnt)
774
- }
775
- recalculate()
776
- })
777
- }
778
-
779
- const submitEvent = (evnt: Event) => {
780
- evnt.preventDefault()
781
- if (!props.preventSubmit) {
782
- handleSubmitEvent(evnt)
783
- }
784
- }
785
-
786
- const closeTooltip = () => {
787
- const { tooltipStore } = internalData
788
- const $tooltip = refTooltip.value
789
- if (tooltipStore.visible) {
790
- Object.assign(tooltipStore, {
791
- item: null,
792
- visible: false
793
- })
794
- if ($tooltip) {
795
- $tooltip.close()
796
- }
797
- }
798
- return nextTick()
799
- }
800
-
801
- const triggerTitleTipEvent = (evnt: MouseEvent, params: {
802
- item: VxeFormDefines.ItemInfo;
803
- }) => {
804
- const { item } = params
805
- const { tooltipStore } = internalData
806
- const $tooltip = refTooltip.value
807
- const overflowElem = (evnt.currentTarget as HTMLDivElement).children[0]
808
- const content = (overflowElem.textContent || '').trim()
809
- const isCellOverflow = overflowElem.scrollWidth > overflowElem.clientWidth
810
- clearTimeout(internalData.stTimeout)
811
- if (tooltipStore.item !== item) {
812
- closeTooltip()
813
- }
814
- if (content && isCellOverflow) {
815
- Object.assign(tooltipStore, {
816
- item,
817
- visible: true
818
- })
819
- if ($tooltip) {
820
- $tooltip.open(overflowElem, content)
821
- }
822
- }
823
- }
824
-
825
- const handleTitleTipLeaveEvent = () => {
826
- const tooltipOpts = computeTooltipOpts.value
827
- let $tooltip = refTooltip.value
828
- if ($tooltip) {
829
- $tooltip.setActived(false)
830
- }
831
- if (tooltipOpts.enterable) {
832
- internalData.stTimeout = setTimeout(() => {
833
- $tooltip = refTooltip.value
834
- if ($tooltip && !$tooltip.isActived()) {
835
- closeTooltip()
836
- }
837
- }, tooltipOpts.leaveDelay)
838
- } else {
839
- closeTooltip()
840
- }
841
- }
842
-
843
- const triggerItemEvent = (evnt: Event, field: string, itemValue?: any) => {
844
- if (field) {
845
- return validItemRules(evnt ? (['blur'].includes(evnt.type) ? 'blur' : 'change') : 'all', field, itemValue)
846
- .then(() => {
847
- clearValidate(field)
848
- })
849
- .catch((errorMaps: VxeFormDefines.ValidateErrorMapParams) => {
850
- const rest = errorMaps[field]
851
- const item = getItemByField(field)
852
- if (rest && item) {
853
- item.showError = true
854
- item.errRule = rest[0].rule
855
- }
856
- })
857
- }
858
- return nextTick()
859
- }
860
-
861
- /**
862
- * 更新项状态
863
- * 如果组件值 v-model 发生 change 时,调用改函数用于更新某一项编辑状态
864
- * 如果单元格配置了校验规则,则会进行校验
865
- */
866
- const updateStatus = (scope: any, itemValue?: any) => {
867
- const { field } = scope
868
- return triggerItemEvent(new Event('change'), field, itemValue)
869
- }
870
-
871
- const recalculate = () => {
872
- const autoItemWidthList = computeAutoItemWidthList.value
873
- const el = refElem.value
874
- if (el && autoItemWidthList.length) {
875
- const itemElList = el.querySelectorAll<HTMLElement>(autoItemWidthList.map(item => `.vxe-form--item-title[itemid="${item.id}"]`).join(','))
876
- let maxItemWidth = 0
877
- XEUtils.arrayEach(itemElList, itemEl => {
878
- itemEl.style.width = ''
879
- maxItemWidth = Math.max(maxItemWidth, Math.ceil(itemEl.clientWidth + 2))
880
- })
881
- XEUtils.arrayEach(itemElList, itemEl => {
882
- itemEl.style.width = `${maxItemWidth}px`
883
- })
884
- }
885
- return nextTick()
886
- }
887
-
888
- const handleGlobalResizeEvent = () => {
889
- recalculate()
890
- }
891
-
892
- const handleItemVisible = (visible: boolean) => {
893
- return function (fieldOrItems?: VxeFormItemPropTypes.Field | VxeFormItemPropTypes.Field[] | VxeFormDefines.ItemInfo | VxeFormDefines.ItemInfo[] | null) {
894
- const objs = XEUtils.isArray(fieldOrItems) ? fieldOrItems : [fieldOrItems]
895
- objs.forEach(obj => {
896
- const item = handleFieldOrItem($xeForm, obj)
897
- if (item) {
898
- item.visible = visible
899
- }
900
- })
901
- return nextTick()
902
- }
903
- }
904
-
905
- const formMethods: FormMethods = {
906
- dispatchEvent,
907
- loadItems,
908
- showItem: handleItemVisible(true),
909
- hideItem: handleItemVisible(false),
910
- reset,
911
- validate,
912
- validateField,
913
- clearValidate,
914
- updateStatus,
915
- toggleCollapse,
916
- getItems,
917
- getFlatItems,
918
- getNestedItems,
919
- getItemByField,
920
- closeTooltip,
921
- recalculate
922
- }
923
-
924
- const formPrivateMethods: VxeFormPrivateMethods = {
925
- callSlot,
926
- triggerItemEvent,
927
- toggleCollapseEvent,
928
- triggerTitleTipEvent,
929
- handleTitleTipLeaveEvent,
930
- handleValidIconEvent (evnt, params) {
931
- const { item } = params
932
- item.showIconMsg = !item.showIconMsg
933
- },
934
- handleSubmitEvent
935
- }
936
-
937
- Object.assign($xeForm, formMethods, formPrivateMethods)
938
-
939
- const renderVN = () => {
940
- const { loading, border, className, data, customLayout } = props
941
- const { formItems } = reactData
942
- const vSize = computeSize.value
943
- const tooltipOpts = computeTooltipOpts.value
944
- const defaultSlot = slots.default
945
- return h('form', {
946
- ref: refElem,
947
- class: ['vxe-form', className ? (XEUtils.isFunction(className) ? className({ items: formItems, data, $form: $xeForm }) : className) : '', {
948
- [`size--${vSize}`]: vSize,
949
- 'is--border': border,
950
- 'custom--layout': customLayout,
951
- 'is--loading': loading
952
- }],
953
- onSubmit: submitEvent,
954
- onReset: resetEvent
955
- }, [
956
- h('div', {
957
- class: 'vxe-form--wrapper vxe-form--item-row'
958
- }, customLayout
959
- ? (defaultSlot ? defaultSlot({}) : [])
960
- : formItems.map((item, index) => {
961
- return h(VxeFormConfigItem, {
962
- key: index,
963
- itemConfig: item,
964
- visible: item.visible
965
- })
966
- })),
967
- h('div', {
968
- class: 'vxe-form-slots'
969
- }, customLayout ? [] : (defaultSlot ? defaultSlot({}) : [])),
970
- /**
971
- * 加载中
972
- */
973
- h(VxeLoadingComponent, {
974
- class: 'vxe-form--loading',
975
- modelValue: loading
976
- }),
977
- /**
978
- * 工具提示
979
- */
980
- h(VxeTooltipComponent, {
981
- ref: refTooltip,
982
- ...tooltipOpts
983
- })
984
- ])
985
- }
986
-
987
- const recalcFlag = ref(0)
988
- watch(() => props.vertical, () => {
989
- recalcFlag.value++
990
- })
991
- watch(() => props.titleWidth, () => {
992
- recalcFlag.value++
993
- })
994
- watch(recalcFlag, () => {
995
- nextTick().then(() => {
996
- recalculate()
997
- })
998
- })
999
-
1000
- const staticItemFlag = ref(0)
1001
- watch(() => reactData.staticItems.length, () => {
1002
- staticItemFlag.value++
1003
- })
1004
- watch(() => reactData.staticItems, () => {
1005
- staticItemFlag.value++
1006
- })
1007
- watch(staticItemFlag, () => {
1008
- reactData.formItems = reactData.staticItems
1009
- recalcFlag.value++
1010
- cacheItem()
1011
- })
1012
-
1013
- const itemFlag = ref(0)
1014
- watch(() => props.items ? props.items.length : -1, () => {
1015
- itemFlag.value++
1016
- })
1017
- watch(() => props.items, () => {
1018
- itemFlag.value++
1019
- })
1020
- watch(itemFlag, () => {
1021
- loadItems(props.items || [])
1022
- })
1023
-
1024
- watch(() => props.collapseStatus, (value) => {
1025
- reactData.collapseAll = !!value
1026
- })
1027
-
1028
- watch(() => props.readonly, () => {
1029
- clearValidate()
1030
- })
1031
-
1032
- watch(() => props.disabled, () => {
1033
- clearValidate()
1034
- })
1035
-
1036
- onMounted(() => {
1037
- nextTick(() => {
1038
- if (props.customLayout && props.items) {
1039
- errLog('vxe.error.errConflicts', ['custom-layout', 'items'])
1040
- }
1041
- })
1042
- globalEvents.on($xeForm, 'resize', handleGlobalResizeEvent)
1043
- })
1044
-
1045
- onUnmounted(() => {
1046
- globalEvents.off($xeForm, 'resize')
1047
- XEUtils.assign(reactData, createReactData())
1048
- XEUtils.assign(internalData, createInternalData())
1049
- })
1050
-
1051
- reactData.collapseAll = !!props.collapseStatus
1052
- if (props.items) {
1053
- loadItems(props.items)
1054
- }
1055
-
1056
- provide('xeFormItemInfo', null)
1057
-
1058
- provide('$xeForm', $xeForm)
1059
- provide('$xeFormGroup', null)
1060
- provide('$xeFormItem', null)
1061
-
1062
- $xeForm.renderVN = renderVN
1063
-
1064
- return $xeForm
1065
- },
1066
- render () {
1067
- return this.renderVN()
1068
- }
1069
- })
1
+ import { h, ref, Ref, provide, computed, inject, reactive, watch, nextTick, PropType, onMounted, onUnmounted } from 'vue'
2
+ import { defineVxeComponent } from '../../ui/src/comp'
3
+ import XEUtils from 'xe-utils'
4
+ import { VxeUI } from '@vxe-ui/core'
5
+ import { eqEmptyValue, getFuncText, isEnableConf } from '../../ui/src/utils'
6
+ import { scrollToView } from '../../ui/src/dom'
7
+ import { createItem, handleFieldOrItem, isHiddenItem, isActiveItem } from './util'
8
+ import VxeTooltipComponent from '../../tooltip'
9
+ import VxeFormConfigItem from './form-config-item'
10
+ import VxeLoadingComponent from '../../loading'
11
+ import { getSlotVNs } from '../../ui/src/vn'
12
+ import { createComponentLog } from '../../ui/src/log'
13
+
14
+ import '../render'
15
+
16
+ import type { VxeFormConstructor, VxeFormPropTypes, VxeFormEmits, FormReactData, FormMethods, FormPrivateRef, VxeFormPrivateMethods, VxeFormDefines, VxeFormItemPropTypes, VxeTooltipInstance, FormInternalData, VxeFormPrivateComputed, ValueOf } from '../../../types'
17
+ import type { VxeGridConstructor, VxeGridPrivateMethods } from '../../../types/components/grid'
18
+
19
+ const { getConfig, validators, renderer, createEvent, useFns, globalEvents } = VxeUI
20
+
21
+ const { warnLog, errLog } = createComponentLog('form')
22
+
23
+ class Rule {
24
+ constructor(rule: any) {
25
+ Object.assign(this, {
26
+ $options: rule,
27
+ required: rule.required,
28
+ min: rule.min,
29
+ max: rule.min,
30
+ type: rule.type,
31
+ pattern: rule.pattern,
32
+ validator: rule.validator,
33
+ trigger: rule.trigger,
34
+ maxWidth: rule.maxWidth
35
+ })
36
+ }
37
+
38
+ get content() {
39
+ return getFuncText(this.$options.content || this.$options.message)
40
+ }
41
+
42
+ get message() {
43
+ return this.content
44
+ }
45
+
46
+ [key: string]: any
47
+ }
48
+
49
+ // 如果存在 pattern,判断正则
50
+ function validREValue(pattern: string | RegExp | undefined, val: string) {
51
+ if (pattern && !(XEUtils.isRegExp(pattern) ? pattern : new RegExp(pattern)).test(val)) {
52
+ return false
53
+ }
54
+ return true
55
+ }
56
+
57
+ // 如果存在 max,判断最大值
58
+ function validMaxValue(max: string | number | undefined, num: number) {
59
+ if (!XEUtils.eqNull(max) && num > XEUtils.toNumber(max)) {
60
+ return false
61
+ }
62
+ return true
63
+ }
64
+
65
+ // 如果存在 min,判断最小值
66
+ function validMinValue(min: string | number | undefined, num: number) {
67
+ if (!XEUtils.eqNull(min) && num < XEUtils.toNumber(min)) {
68
+ return false
69
+ }
70
+ return true
71
+ }
72
+
73
+ function validRuleValue(rule: VxeFormDefines.FormRule, val: any, required: boolean | undefined) {
74
+ const { type, min, max, pattern } = rule
75
+ const isArrType = type === 'array'
76
+ const isNumType = type === 'number'
77
+ const isStrType = type === 'string'
78
+ const strVal = `${val}`
79
+ if (!validREValue(pattern, strVal)) {
80
+ return false
81
+ }
82
+ if (isArrType) {
83
+ if (!XEUtils.isArray(val)) {
84
+ return false
85
+ }
86
+ if (required) {
87
+ if (!val.length) {
88
+ return false
89
+ }
90
+ }
91
+ if (!validMinValue(min, val.length)) {
92
+ return false
93
+ }
94
+ if (!validMaxValue(max, val.length)) {
95
+ return false
96
+ }
97
+ } else if (isNumType) {
98
+ const numVal = Number(val)
99
+ if (isNaN(numVal)) {
100
+ return false
101
+ }
102
+ if (!validMinValue(min, numVal)) {
103
+ return false
104
+ }
105
+ if (!validMaxValue(max, numVal)) {
106
+ return false
107
+ }
108
+ } else {
109
+ if (isStrType) {
110
+ if (!XEUtils.isString(val)) {
111
+ return false
112
+ }
113
+ }
114
+ if (required) {
115
+ if (!strVal) {
116
+ return false
117
+ }
118
+ }
119
+ if (!validMinValue(min, strVal.length)) {
120
+ return false
121
+ }
122
+ if (!validMaxValue(max, strVal.length)) {
123
+ return false
124
+ }
125
+ }
126
+ return true
127
+ }
128
+
129
+ function checkRuleStatus(rule: VxeFormDefines.FormRule, data: any, val: any) {
130
+ const { required, field } = rule
131
+ const currVal = field ? XEUtils.get(data, field) : val
132
+ const isEmptyVal = XEUtils.isArray(currVal) ? !currVal.length : eqEmptyValue(currVal)
133
+ if (required) {
134
+ if (isEmptyVal) {
135
+ return false
136
+ }
137
+ if (!validRuleValue(rule, currVal, required)) {
138
+ return false
139
+ }
140
+ } else {
141
+ if (!isEmptyVal) {
142
+ if (!validRuleValue(rule, currVal, required)) {
143
+ return false
144
+ }
145
+ }
146
+ }
147
+ return true
148
+ }
149
+
150
+ export function createReactData(): FormReactData {
151
+ return {
152
+ collapseAll: false,
153
+ staticItems: [],
154
+ formItems: [],
155
+ itemWidth: 0
156
+ }
157
+ }
158
+
159
+ function createInternalData(): FormInternalData {
160
+ return {
161
+ meTimeout: undefined,
162
+ stTimeout: undefined,
163
+ tooltipStore: {
164
+ item: null,
165
+ visible: false
166
+ },
167
+ itemFormatCache: {},
168
+ fullItemList: [],
169
+ fullItemIdData: {},
170
+ fullItemFieldData: {}
171
+ }
172
+ }
173
+
174
+ export default defineVxeComponent({
175
+ name: 'VxeForm',
176
+ props: {
177
+ collapseStatus: {
178
+ type: Boolean as PropType<VxeFormPropTypes.CollapseStatus>,
179
+ default: true
180
+ },
181
+ loading: Boolean as PropType<VxeFormPropTypes.Loading>,
182
+ data: Object as PropType<VxeFormPropTypes.Data>,
183
+ size: {
184
+ type: String as PropType<VxeFormPropTypes.Size>,
185
+ default: () => getConfig().form.size || getConfig().size
186
+ },
187
+ span: {
188
+ type: [String, Number] as PropType<VxeFormPropTypes.Span>,
189
+ default: () => getConfig().form.span
190
+ },
191
+ align: {
192
+ type: String as PropType<VxeFormPropTypes.Align>,
193
+ default: () => getConfig().form.align
194
+ },
195
+ verticalAlign: {
196
+ type: String as PropType<VxeFormPropTypes.VerticalAlign>,
197
+ default: () => getConfig().form.verticalAlign
198
+ },
199
+ border: {
200
+ type: Boolean as PropType<VxeFormPropTypes.Border>,
201
+ default: () => getConfig().form.border
202
+ },
203
+ titleBackground: {
204
+ type: Boolean as PropType<VxeFormPropTypes.TitleBackground>,
205
+ default: () => getConfig().form.titleBackground
206
+ },
207
+ titleBold: {
208
+ type: Boolean as PropType<VxeFormPropTypes.TitleBold>,
209
+ default: () => getConfig().form.titleBold
210
+ },
211
+ titleAlign: {
212
+ type: String as PropType<VxeFormPropTypes.TitleAlign>,
213
+ default: () => getConfig().form.titleAlign
214
+ },
215
+ titleWidth: {
216
+ type: [String, Number] as PropType<VxeFormPropTypes.TitleWidth>,
217
+ default: () => getConfig().form.titleWidth
218
+ },
219
+ titleColon: {
220
+ type: Boolean as PropType<VxeFormPropTypes.TitleColon>,
221
+ default: () => getConfig().form.titleColon
222
+ },
223
+ titleAsterisk: {
224
+ type: Boolean as PropType<VxeFormPropTypes.TitleAsterisk>,
225
+ default: () => getConfig().form.titleAsterisk
226
+ },
227
+ titleOverflow: {
228
+ type: [Boolean, String] as PropType<VxeFormPropTypes.TitleOverflow>,
229
+ default: () => getConfig().form.titleOverflow
230
+ },
231
+ vertical: {
232
+ type: Boolean as PropType<VxeFormPropTypes.Vertical>,
233
+ default: () => getConfig().form.vertical
234
+ },
235
+ padding: {
236
+ type: Boolean as PropType<VxeFormPropTypes.Padding>,
237
+ default: () => getConfig().form.padding
238
+ },
239
+ className: [String, Function] as PropType<VxeFormPropTypes.ClassName>,
240
+ readonly: Boolean as PropType<VxeFormPropTypes.Readonly>,
241
+ disabled: Boolean as PropType<VxeFormPropTypes.Disabled>,
242
+ items: Array as PropType<VxeFormPropTypes.Items>,
243
+ rules: Object as PropType<VxeFormPropTypes.Rules>,
244
+ preventSubmit: {
245
+ type: Boolean as PropType<VxeFormPropTypes.PreventSubmit>,
246
+ default: () => getConfig().form.preventSubmit
247
+ },
248
+ validConfig: Object as PropType<VxeFormPropTypes.ValidConfig>,
249
+ tooltipConfig: Object as PropType<VxeFormPropTypes.TooltipConfig>,
250
+ collapseConfig: Object as PropType<VxeFormPropTypes.CollapseConfig>,
251
+ customLayout: {
252
+ type: Boolean as PropType<VxeFormPropTypes.CustomLayout>,
253
+ default: () => getConfig().form.customLayout
254
+ },
255
+ params: Object as PropType<VxeFormPropTypes.Params>
256
+ },
257
+ emits: ['update:collapseStatus', 'collapse', 'toggle-collapse', 'submit', 'submit-invalid', 'reset'] as VxeFormEmits,
258
+ setup(props, context) {
259
+ const { slots, emit } = context
260
+
261
+ const $xeGrid = inject<(VxeGridConstructor & VxeGridPrivateMethods) | null>('$xeGrid', null)
262
+
263
+ const xID = XEUtils.uniqueId()
264
+
265
+ const { computeSize } = useFns.useSize(props)
266
+
267
+ const reactData = reactive(createReactData())
268
+
269
+ const internalData = createInternalData()
270
+
271
+ const refElem = ref<HTMLFormElement>()
272
+ const refTooltip = ref() as Ref<VxeTooltipInstance>
273
+
274
+ const computeValidOpts = computed(() => {
275
+ return Object.assign({}, getConfig().form.validConfig, props.validConfig)
276
+ })
277
+
278
+ const computeTooltipOpts = computed(() => {
279
+ return Object.assign({}, getConfig().tooltip, getConfig().form.tooltipConfig, props.tooltipConfig)
280
+ })
281
+
282
+ const computeCollapseOpts = computed(() => {
283
+ return Object.assign({}, getConfig().form.collapseConfig, props.collapseConfig)
284
+ })
285
+
286
+ const computeAutoItemWidthList = computed(() => {
287
+ const { titleWidth: allTitleWidth, vertical: allVertical } = props
288
+ const { formItems } = reactData
289
+ const itemList: VxeFormDefines.ItemInfo[] = []
290
+ XEUtils.eachTree(
291
+ formItems,
292
+ (item) => {
293
+ const { titleWidth, vertical } = item
294
+ if (titleWidth === 'auto') {
295
+ itemList.push(item)
296
+ } else {
297
+ const itemVertical = XEUtils.eqNull(vertical) ? allVertical : vertical
298
+ const itemTitleWidth = itemVertical ? null : XEUtils.eqNull(titleWidth) ? allTitleWidth : titleWidth
299
+ if (itemTitleWidth === 'auto' && (!item.children || !item.children.length)) {
300
+ itemList.push(item)
301
+ }
302
+ }
303
+ },
304
+ { children: 'children' }
305
+ )
306
+ return itemList
307
+ })
308
+
309
+ const refMaps: FormPrivateRef = {
310
+ refElem
311
+ }
312
+
313
+ const computeMaps: VxeFormPrivateComputed = {
314
+ computeSize,
315
+ computeValidOpts,
316
+ computeTooltipOpts,
317
+ computeCollapseOpts,
318
+ computeAutoItemWidthList
319
+ }
320
+
321
+ const $xeForm = {
322
+ xID,
323
+ props,
324
+ context,
325
+ reactData,
326
+ internalData,
327
+
328
+ xeGrid: $xeGrid,
329
+ getRefMaps: () => refMaps,
330
+ getComputeMaps: () => computeMaps
331
+ } as unknown as VxeFormConstructor & VxeFormPrivateMethods
332
+
333
+ const dispatchEvent = (type: ValueOf<VxeFormEmits>, params: Record<string, any>, evnt: Event | null) => {
334
+ emit(type, createEvent(evnt, { $form: $xeForm, $grid: $xeGrid }, params))
335
+ }
336
+
337
+ const callSlot = (slotFunc: ((params: any) => any) | string | null, params: any) => {
338
+ if (slotFunc) {
339
+ if (XEUtils.isString(slotFunc)) {
340
+ slotFunc = slots[slotFunc] || null
341
+ }
342
+ if (XEUtils.isFunction(slotFunc)) {
343
+ return getSlotVNs(slotFunc(params))
344
+ }
345
+ }
346
+ return []
347
+ }
348
+
349
+ const loadItems = (list: VxeFormPropTypes.Items) => {
350
+ if (list.length) {
351
+ list.forEach((item) => {
352
+ if (item.slots) {
353
+ XEUtils.each(item.slots, (func) => {
354
+ if (func && !XEUtils.isFunction(func)) {
355
+ if (!slots[func]) {
356
+ errLog('vxe.error.notSlot', [func])
357
+ }
358
+ }
359
+ })
360
+ }
361
+ })
362
+ }
363
+ reactData.staticItems = XEUtils.mapTree(list, (item) => createItem($xeForm, item), { children: 'children' })
364
+ internalData.itemFormatCache = {}
365
+ return nextTick().then(() => {
366
+ return recalculate()
367
+ })
368
+ }
369
+
370
+ /**
371
+ * 已废弃,被 getFormFlatItems 替换
372
+ * @deprecated
373
+ */
374
+ const getItems = () => {
375
+ // errLog('vxe.error.delFunc', ['getItems', 'getFlatItems'])
376
+ return getFlatItems()
377
+ }
378
+
379
+ const getFlatItems = () => {
380
+ return internalData.fullItemList
381
+ }
382
+
383
+ const getNestedItems = () => {
384
+ return reactData.formItems
385
+ }
386
+
387
+ const getItemByField = (field: string) => {
388
+ const { fullItemFieldData } = internalData
389
+ const itemRest = fullItemFieldData[field]
390
+ return itemRest ? itemRest.item : null
391
+ }
392
+
393
+ const getCollapseStatus = () => {
394
+ return reactData.collapseAll
395
+ }
396
+
397
+ const toggleCollapse = () => {
398
+ const status = !getCollapseStatus()
399
+ reactData.collapseAll = status
400
+ emit('update:collapseStatus', status)
401
+ return nextTick()
402
+ }
403
+
404
+ const toggleCollapseEvent = (evnt: Event) => {
405
+ const actionRest = toggleCollapse()
406
+ const status = getCollapseStatus()
407
+ dispatchEvent('toggle-collapse', { status, collapse: status, data: props.data }, evnt)
408
+ dispatchEvent('collapse', { status, collapse: status, data: props.data }, evnt)
409
+ actionRest.then(() => {
410
+ recalculate().then(() => {
411
+ if ($xeGrid) {
412
+ $xeGrid.recalculate(true)
413
+ }
414
+ })
415
+ if ($xeGrid) {
416
+ $xeGrid.recalculate()
417
+ }
418
+ })
419
+ }
420
+
421
+ const clearValidate = (fieldOrItem?: VxeFormItemPropTypes.Field | VxeFormItemPropTypes.Field[] | VxeFormDefines.ItemInfo | VxeFormDefines.ItemInfo[]) => {
422
+ const { fullItemList } = internalData
423
+ if (fieldOrItem) {
424
+ let fields: any = fieldOrItem
425
+ if (!XEUtils.isArray(fieldOrItem)) {
426
+ fields = [fieldOrItem]
427
+ }
428
+ fields.forEach((field: any) => {
429
+ if (field) {
430
+ const item = handleFieldOrItem($xeForm, field)
431
+ if (item) {
432
+ item.showError = false
433
+ item.showIconMsg = false
434
+ }
435
+ }
436
+ })
437
+ } else {
438
+ fullItemList.forEach((item) => {
439
+ item.showError = false
440
+ item.showIconMsg = false
441
+ })
442
+ }
443
+ return nextTick()
444
+ }
445
+
446
+ const getResetValue = (item: VxeFormDefines.ItemInfo, data: any, itemValue: any, currentField?: string) => {
447
+ const { field, resetValue } = item
448
+ if (XEUtils.isFunction(resetValue)) {
449
+ return resetValue({
450
+ field,
451
+ item,
452
+ data,
453
+ currentField: currentField || field || '',
454
+ currentValue: itemValue,
455
+ $form: $xeForm,
456
+ $grid: $xeGrid
457
+ })
458
+ } else if (XEUtils.eqNull(resetValue)) {
459
+ // 默认
460
+ if (XEUtils.isArray(itemValue)) {
461
+ return []
462
+ }
463
+ }
464
+ return resetValue
465
+ }
466
+
467
+ const cacheItem = () => {
468
+ const { formItems } = reactData
469
+ const itemIdData: Record<string, VxeFormDefines.ItemCacheItem> = {}
470
+ const itemFieldData: Record<string, VxeFormDefines.ItemCacheItem> = {}
471
+ const itemList: VxeFormDefines.ItemInfo[] = []
472
+ XEUtils.eachTree(
473
+ formItems,
474
+ (item, index, items) => {
475
+ const { id, field } = item
476
+ const itemRest = { item, items, index }
477
+ if (id) {
478
+ itemIdData[id] = itemRest
479
+ }
480
+ if (field) {
481
+ itemFieldData[field] = itemRest
482
+ }
483
+ itemList.push(item)
484
+ },
485
+ { children: 'children' }
486
+ )
487
+ internalData.fullItemList = itemList
488
+ internalData.fullItemFieldData = itemFieldData
489
+ internalData.fullItemIdData = itemIdData
490
+ }
491
+
492
+ const reset = () => {
493
+ const { data } = props
494
+ const { fullItemList } = internalData
495
+ if (data) {
496
+ fullItemList.forEach((item) => {
497
+ const { field, itemRender } = item
498
+ if (isEnableConf(itemRender)) {
499
+ const { name, startField, endField } = itemRender
500
+ const compConf = renderer.get(name)
501
+ const fiResetMethod = compConf ? compConf.formItemResetMethod || compConf.itemResetMethod : null
502
+ if (compConf && fiResetMethod) {
503
+ fiResetMethod({ data, field, property: field, item, $form: $xeForm, $grid: $xeGrid })
504
+ } else if (field) {
505
+ const itemValue = XEUtils.get(data, field)
506
+ XEUtils.set(data, field, getResetValue(item, data, itemValue))
507
+ }
508
+ if (startField && endField) {
509
+ XEUtils.set(data, startField, getResetValue(item, data, XEUtils.get(data, startField), startField))
510
+ XEUtils.set(data, endField, getResetValue(item, data, XEUtils.get(data, endField), endField))
511
+ }
512
+
513
+ if (field === 'startxxxx') {
514
+ return ''
515
+ } else if (field === 'endxxx') {
516
+ return ''
517
+ }
518
+ return ''
519
+ }
520
+ })
521
+ }
522
+ internalData.itemFormatCache = {}
523
+ clearValidate()
524
+ return recalculate()
525
+ }
526
+
527
+ const resetEvent = (evnt: Event) => {
528
+ evnt.preventDefault()
529
+ reset()
530
+ dispatchEvent('reset', { data: props.data }, evnt)
531
+ }
532
+
533
+ const handleFocus = (fields: string[]) => {
534
+ const el = refElem.value
535
+ if (el) {
536
+ for (let i = 0; i < fields.length; i++) {
537
+ const field = fields[i]
538
+ const item = getItemByField(field)
539
+ if (item && isEnableConf(item.itemRender)) {
540
+ const { itemRender } = item
541
+ const compConf = renderer.get(itemRender.name)
542
+ // 定位到第一个
543
+ if (!i) {
544
+ scrollToView(el.querySelector(`.${item.id}`))
545
+ }
546
+ let inputElem: HTMLElement | null = null
547
+ const autoFocus = itemRender.autoFocus || itemRender.autofocus || (compConf ? compConf.formItemAutoFocus : null)
548
+ // 如果指定了聚焦 class
549
+ if (XEUtils.isFunction(autoFocus)) {
550
+ inputElem = autoFocus({ $form: $xeForm, $grid: $xeGrid, item, data: props.data, field })
551
+ } else {
552
+ if (autoFocus === true) {
553
+ // 自动匹配模式,会自动匹配第一个可输入元素
554
+ inputElem = el.querySelector(`.${item.id} input,textarea`)
555
+ } else if (autoFocus) {
556
+ inputElem = el.querySelector(`.${item.id} ${autoFocus}`) as HTMLInputElement
557
+ }
558
+ }
559
+ if (inputElem) {
560
+ inputElem.focus()
561
+ break
562
+ }
563
+ }
564
+ }
565
+ }
566
+ }
567
+
568
+ /**
569
+ * 校验数据
570
+ * 按表格行、列顺序依次校验(同步或异步)
571
+ * 校验规则根据索引顺序依次校验,如果是异步则会等待校验完成才会继续校验下一列
572
+ * 如果校验失败则,触发回调或者 Promise<(ErrMap 校验不通过列的信息)>
573
+ * 如果是传回调方式这返回一个 (ErrMap 校验不通过列的信息)
574
+ *
575
+ * rule 配置:
576
+ * required=Boolean 是否必填
577
+ * min=Number 最小长度
578
+ * max=Number 最大长度
579
+ * validator=Function({ itemValue, rule, rules, data, property }) 自定义校验,接收一个 Promise
580
+ * trigger=change 触发方式
581
+ */
582
+ const validItemRules = (validType: string, fields: string | string[], val?: any): Promise<VxeFormDefines.ValidateErrorMapParams | undefined> => {
583
+ const { data, rules: formRules } = props
584
+ const errorMaps: VxeFormDefines.ValidateErrorMapParams = {}
585
+ if (!XEUtils.isArray(fields)) {
586
+ fields = [fields]
587
+ }
588
+ return Promise.all(
589
+ fields.map((property) => {
590
+ const errorRules: Rule[] = []
591
+ const syncVailds: Promise<any>[] = []
592
+ if (property && formRules) {
593
+ const item = getItemByField(property)
594
+ const rules = item && item.rules ? item.rules : XEUtils.get(formRules, property)
595
+ if (rules) {
596
+ const itemValue = XEUtils.isUndefined(val) ? XEUtils.get(data, property) : val
597
+ rules.forEach((rule) => {
598
+ const { trigger, validator } = rule
599
+ if (validType === 'all' || !trigger || validType === trigger) {
600
+ if (validator) {
601
+ const validParams = {
602
+ itemValue,
603
+ rule,
604
+ rules,
605
+ data,
606
+ field: property,
607
+ property,
608
+ $form: $xeForm
609
+ }
610
+ let customValid: any
611
+ if (XEUtils.isString(validator)) {
612
+ const gvItem = validators.get(validator)
613
+ if (gvItem) {
614
+ const validatorMethod = gvItem.formItemValidatorMethod || gvItem.itemValidatorMethod
615
+ if (validatorMethod) {
616
+ customValid = validatorMethod(validParams)
617
+ } else {
618
+ warnLog('vxe.error.notValidators', [validator])
619
+ }
620
+ } else {
621
+ errLog('vxe.error.notValidators', [validator])
622
+ }
623
+ } else {
624
+ customValid = validator(validParams)
625
+ }
626
+ if (customValid) {
627
+ if (XEUtils.isError(customValid)) {
628
+ errorRules.push(new Rule({ type: 'custom', trigger, content: customValid.message, rule: new Rule(rule) }))
629
+ } else if (customValid.catch) {
630
+ // 如果为异步校验(注:异步校验是并发无序的)
631
+ syncVailds.push(
632
+ customValid.catch((e: any) => {
633
+ errorRules.push(new Rule({ type: 'custom', trigger, content: e ? e.message : rule.content || rule.message, rule: new Rule(rule) }))
634
+ })
635
+ )
636
+ }
637
+ }
638
+ } else {
639
+ if (!checkRuleStatus(rule, data, itemValue)) {
640
+ errorRules.push(new Rule(rule))
641
+ }
642
+ }
643
+ }
644
+ })
645
+ }
646
+ }
647
+ return Promise.all(syncVailds).then(() => {
648
+ if (errorRules.length) {
649
+ errorMaps[property] = errorRules.map((rule) => {
650
+ return {
651
+ $form: $xeForm,
652
+ rule,
653
+ data,
654
+ field: property,
655
+ property
656
+ }
657
+ })
658
+ }
659
+ })
660
+ })
661
+ ).then(() => {
662
+ if (!XEUtils.isEmpty(errorMaps)) {
663
+ return Promise.reject(errorMaps)
664
+ }
665
+ })
666
+ }
667
+
668
+ const beginValidate = (itemList: VxeFormDefines.ItemInfo[], type?: string, callback?: any): Promise<VxeFormDefines.ValidateErrorMapParams | void> => {
669
+ const { data, rules: formRules } = props
670
+ const validOpts = computeValidOpts.value
671
+ const validRest: any = {}
672
+ const validFields: string[] = []
673
+ const itemValids: any[] = []
674
+ clearTimeout(internalData.meTimeout)
675
+ if (data && formRules) {
676
+ itemList.forEach((item) => {
677
+ const { field } = item
678
+ if (field && !isHiddenItem($xeForm, item) && isActiveItem($xeForm, item)) {
679
+ itemValids.push(
680
+ validItemRules(type || 'all', field)
681
+ .then(() => {
682
+ item.errRule = null
683
+ })
684
+ .catch((errorMaps: VxeFormDefines.ValidateErrorMapParams) => {
685
+ const rest = errorMaps[field]
686
+ if (!validRest[field]) {
687
+ validRest[field] = []
688
+ }
689
+ validRest[field].push(rest)
690
+ validFields.push(field)
691
+ item.errRule = rest[0].rule
692
+ return Promise.reject(rest)
693
+ })
694
+ )
695
+ }
696
+ })
697
+ return Promise.all(itemValids)
698
+ .then(() => {
699
+ if (callback) {
700
+ callback()
701
+ }
702
+ })
703
+ .catch(() => {
704
+ return new Promise<void>((resolve) => {
705
+ internalData.meTimeout = setTimeout(() => {
706
+ itemList.forEach((item) => {
707
+ if (item.errRule) {
708
+ item.showError = true
709
+ }
710
+ })
711
+ }, 20)
712
+ if (validOpts.autoPos !== false) {
713
+ nextTick(() => {
714
+ handleFocus(validFields)
715
+ })
716
+ }
717
+ if (callback) {
718
+ callback(validRest)
719
+ resolve()
720
+ } else {
721
+ resolve(validRest)
722
+ }
723
+ })
724
+ })
725
+ }
726
+ if (callback) {
727
+ callback()
728
+ }
729
+ return Promise.resolve()
730
+ }
731
+
732
+ const validate = (callback: any): Promise<any> => {
733
+ const { readonly } = props
734
+ const { fullItemList } = internalData
735
+ clearValidate()
736
+ if (readonly) {
737
+ return Promise.resolve()
738
+ }
739
+ return beginValidate(fullItemList, '', callback).then((params) => {
740
+ recalculate()
741
+ return params
742
+ })
743
+ }
744
+
745
+ const validateField = (fieldOrItem: VxeFormItemPropTypes.Field | VxeFormItemPropTypes.Field[] | VxeFormDefines.ItemInfo | VxeFormDefines.ItemInfo[], callback: any) => {
746
+ const { readonly } = props
747
+ if (readonly) {
748
+ return Promise.resolve()
749
+ }
750
+ let fields: any[] = []
751
+ if (fieldOrItem) {
752
+ if (XEUtils.isArray(fieldOrItem)) {
753
+ fields = fieldOrItem
754
+ } else {
755
+ fields = [fieldOrItem]
756
+ }
757
+ }
758
+ const itemList = fields.map((field) => handleFieldOrItem($xeForm, field)) as VxeFormDefines.ItemInfo[]
759
+ return beginValidate(itemList, '', callback).then((params) => {
760
+ recalculate()
761
+ return params
762
+ })
763
+ }
764
+
765
+ const handleSubmitEvent = (evnt: Event) => {
766
+ const { readonly } = props
767
+ const { fullItemList } = internalData
768
+ clearValidate()
769
+ if (readonly) {
770
+ dispatchEvent('submit', { data: props.data }, evnt)
771
+ recalculate()
772
+ return
773
+ }
774
+ beginValidate(fullItemList).then((errMap) => {
775
+ if (errMap) {
776
+ dispatchEvent('submit-invalid', { data: props.data, errMap }, evnt)
777
+ } else {
778
+ dispatchEvent('submit', { data: props.data }, evnt)
779
+ }
780
+ recalculate()
781
+ })
782
+ }
783
+
784
+ const submitEvent = (evnt: Event) => {
785
+ evnt.preventDefault()
786
+ if (!props.preventSubmit) {
787
+ handleSubmitEvent(evnt)
788
+ }
789
+ }
790
+
791
+ const closeTooltip = () => {
792
+ const { tooltipStore } = internalData
793
+ const $tooltip = refTooltip.value
794
+ if (tooltipStore.visible) {
795
+ Object.assign(tooltipStore, {
796
+ item: null,
797
+ visible: false
798
+ })
799
+ if ($tooltip) {
800
+ $tooltip.close()
801
+ }
802
+ }
803
+ return nextTick()
804
+ }
805
+
806
+ const triggerTitleTipEvent = (
807
+ evnt: MouseEvent,
808
+ params: {
809
+ item: VxeFormDefines.ItemInfo
810
+ }
811
+ ) => {
812
+ const { item } = params
813
+ const { tooltipStore } = internalData
814
+ const $tooltip = refTooltip.value
815
+ const overflowElem = (evnt.currentTarget as HTMLDivElement).children[0]
816
+ const content = (overflowElem.textContent || '').trim()
817
+ const isCellOverflow = overflowElem.scrollWidth > overflowElem.clientWidth
818
+ clearTimeout(internalData.stTimeout)
819
+ if (tooltipStore.item !== item) {
820
+ closeTooltip()
821
+ }
822
+ if (content && isCellOverflow) {
823
+ Object.assign(tooltipStore, {
824
+ item,
825
+ visible: true
826
+ })
827
+ if ($tooltip) {
828
+ $tooltip.open(overflowElem, content)
829
+ }
830
+ }
831
+ }
832
+
833
+ const handleTitleTipLeaveEvent = () => {
834
+ const tooltipOpts = computeTooltipOpts.value
835
+ let $tooltip = refTooltip.value
836
+ if ($tooltip) {
837
+ $tooltip.setActived(false)
838
+ }
839
+ if (tooltipOpts.enterable) {
840
+ internalData.stTimeout = setTimeout(() => {
841
+ $tooltip = refTooltip.value
842
+ if ($tooltip && !$tooltip.isActived()) {
843
+ closeTooltip()
844
+ }
845
+ }, tooltipOpts.leaveDelay)
846
+ } else {
847
+ closeTooltip()
848
+ }
849
+ }
850
+
851
+ const triggerItemEvent = (evnt: Event, field: string, itemValue?: any) => {
852
+ if (field) {
853
+ return validItemRules(evnt ? (['blur'].includes(evnt.type) ? 'blur' : 'change') : 'all', field, itemValue)
854
+ .then(() => {
855
+ clearValidate(field)
856
+ })
857
+ .catch((errorMaps: VxeFormDefines.ValidateErrorMapParams) => {
858
+ const rest = errorMaps[field]
859
+ const item = getItemByField(field)
860
+ if (rest && item) {
861
+ item.showError = true
862
+ item.errRule = rest[0].rule
863
+ }
864
+ })
865
+ }
866
+ return nextTick()
867
+ }
868
+
869
+ /**
870
+ * 更新项状态
871
+ * 如果组件值 v-model 发生 change 时,调用改函数用于更新某一项编辑状态
872
+ * 如果单元格配置了校验规则,则会进行校验
873
+ */
874
+ const updateStatus = (scope: any, itemValue?: any) => {
875
+ const { field } = scope
876
+ return triggerItemEvent(new Event('change'), field, itemValue)
877
+ }
878
+
879
+ const recalculate = () => {
880
+ const autoItemWidthList = computeAutoItemWidthList.value
881
+ const el = refElem.value
882
+ if (el && autoItemWidthList.length) {
883
+ const itemElList = el.querySelectorAll<HTMLElement>(autoItemWidthList.map((item) => `.vxe-form--item-title[itemid="${item.id}"]`).join(','))
884
+ let maxItemWidth = 0
885
+ XEUtils.arrayEach(itemElList, (itemEl) => {
886
+ itemEl.style.width = ''
887
+ maxItemWidth = Math.max(maxItemWidth, Math.ceil(itemEl.clientWidth + 2))
888
+ })
889
+ XEUtils.arrayEach(itemElList, (itemEl) => {
890
+ itemEl.style.width = `${maxItemWidth}px`
891
+ })
892
+ }
893
+ return nextTick()
894
+ }
895
+
896
+ const handleGlobalResizeEvent = () => {
897
+ recalculate()
898
+ }
899
+
900
+ const handleItemVisible = (visible: boolean) => {
901
+ return function (fieldOrItems?: VxeFormItemPropTypes.Field | VxeFormItemPropTypes.Field[] | VxeFormDefines.ItemInfo | VxeFormDefines.ItemInfo[] | null) {
902
+ const objs = XEUtils.isArray(fieldOrItems) ? fieldOrItems : [fieldOrItems]
903
+ objs.forEach((obj) => {
904
+ const item = handleFieldOrItem($xeForm, obj)
905
+ if (item) {
906
+ item.visible = visible
907
+ }
908
+ })
909
+ return nextTick()
910
+ }
911
+ }
912
+
913
+ const formMethods: FormMethods = {
914
+ dispatchEvent,
915
+ loadItems,
916
+ showItem: handleItemVisible(true),
917
+ hideItem: handleItemVisible(false),
918
+ reset,
919
+ validate,
920
+ validateField,
921
+ clearValidate,
922
+ updateStatus,
923
+ toggleCollapse,
924
+ getItems,
925
+ getFlatItems,
926
+ getNestedItems,
927
+ getItemByField,
928
+ closeTooltip,
929
+ recalculate
930
+ }
931
+
932
+ const formPrivateMethods: VxeFormPrivateMethods = {
933
+ callSlot,
934
+ triggerItemEvent,
935
+ toggleCollapseEvent,
936
+ triggerTitleTipEvent,
937
+ handleTitleTipLeaveEvent,
938
+ handleValidIconEvent(evnt, params) {
939
+ const { item } = params
940
+ item.showIconMsg = !item.showIconMsg
941
+ },
942
+ handleSubmitEvent
943
+ }
944
+
945
+ Object.assign($xeForm, formMethods, formPrivateMethods)
946
+
947
+ const renderVN = () => {
948
+ const { loading, border, className, data, customLayout } = props
949
+ const { formItems } = reactData
950
+ const vSize = computeSize.value
951
+ const tooltipOpts = computeTooltipOpts.value
952
+ const defaultSlot = slots.default
953
+ return h(
954
+ 'form',
955
+ {
956
+ ref: refElem,
957
+ class: [
958
+ 'vxe-form',
959
+ className ? (XEUtils.isFunction(className) ? className({ items: formItems, data, $form: $xeForm }) : className) : '',
960
+ {
961
+ [`size--${vSize}`]: vSize,
962
+ 'is--border': border,
963
+ 'custom--layout': customLayout,
964
+ 'is--loading': loading
965
+ }
966
+ ],
967
+ onSubmit: submitEvent,
968
+ onReset: resetEvent
969
+ },
970
+ [
971
+ h(
972
+ 'div',
973
+ {
974
+ class: 'vxe-form--wrapper vxe-form--item-row'
975
+ },
976
+ customLayout
977
+ ? defaultSlot
978
+ ? defaultSlot({})
979
+ : []
980
+ : formItems.map((item, index) => {
981
+ return h(VxeFormConfigItem, {
982
+ key: index,
983
+ itemConfig: item,
984
+ visible: item.visible
985
+ })
986
+ })
987
+ ),
988
+ h(
989
+ 'div',
990
+ {
991
+ class: 'vxe-form-slots'
992
+ },
993
+ customLayout ? [] : defaultSlot ? defaultSlot({}) : []
994
+ ),
995
+ /**
996
+ * 加载中
997
+ */
998
+ h(VxeLoadingComponent, {
999
+ class: 'vxe-form--loading',
1000
+ modelValue: loading
1001
+ }),
1002
+ /**
1003
+ * 工具提示
1004
+ */
1005
+ h(VxeTooltipComponent, {
1006
+ ref: refTooltip,
1007
+ ...tooltipOpts
1008
+ })
1009
+ ]
1010
+ )
1011
+ }
1012
+
1013
+ const recalcFlag = ref(0)
1014
+ watch(
1015
+ () => props.vertical,
1016
+ () => {
1017
+ recalcFlag.value++
1018
+ }
1019
+ )
1020
+ watch(
1021
+ () => props.titleWidth,
1022
+ () => {
1023
+ recalcFlag.value++
1024
+ }
1025
+ )
1026
+ watch(recalcFlag, () => {
1027
+ nextTick().then(() => {
1028
+ recalculate()
1029
+ })
1030
+ })
1031
+
1032
+ const staticItemFlag = ref(0)
1033
+ watch(
1034
+ () => reactData.staticItems.length,
1035
+ () => {
1036
+ staticItemFlag.value++
1037
+ }
1038
+ )
1039
+ watch(
1040
+ () => reactData.staticItems,
1041
+ () => {
1042
+ staticItemFlag.value++
1043
+ }
1044
+ )
1045
+ watch(staticItemFlag, () => {
1046
+ reactData.formItems = reactData.staticItems
1047
+ recalcFlag.value++
1048
+ cacheItem()
1049
+ })
1050
+
1051
+ const itemFlag = ref(0)
1052
+ watch(
1053
+ () => (props.items ? props.items.length : -1),
1054
+ () => {
1055
+ itemFlag.value++
1056
+ }
1057
+ )
1058
+ watch(
1059
+ () => props.items,
1060
+ () => {
1061
+ itemFlag.value++
1062
+ }
1063
+ )
1064
+ watch(itemFlag, () => {
1065
+ loadItems(props.items || [])
1066
+ })
1067
+
1068
+ watch(
1069
+ () => props.collapseStatus,
1070
+ (value) => {
1071
+ reactData.collapseAll = !!value
1072
+ }
1073
+ )
1074
+
1075
+ watch(
1076
+ () => props.readonly,
1077
+ () => {
1078
+ clearValidate()
1079
+ }
1080
+ )
1081
+
1082
+ watch(
1083
+ () => props.disabled,
1084
+ () => {
1085
+ clearValidate()
1086
+ }
1087
+ )
1088
+
1089
+ onMounted(() => {
1090
+ nextTick(() => {
1091
+ if (props.customLayout && props.items) {
1092
+ errLog('vxe.error.errConflicts', ['custom-layout', 'items'])
1093
+ }
1094
+ })
1095
+ globalEvents.on($xeForm, 'resize', handleGlobalResizeEvent)
1096
+ })
1097
+
1098
+ onUnmounted(() => {
1099
+ globalEvents.off($xeForm, 'resize')
1100
+ XEUtils.assign(reactData, createReactData())
1101
+ XEUtils.assign(internalData, createInternalData())
1102
+ })
1103
+
1104
+ reactData.collapseAll = !!props.collapseStatus
1105
+ if (props.items) {
1106
+ loadItems(props.items)
1107
+ }
1108
+
1109
+ provide('xeFormItemInfo', null)
1110
+
1111
+ provide('$xeForm', $xeForm)
1112
+ provide('$xeFormGroup', null)
1113
+ provide('$xeFormItem', null)
1114
+
1115
+ $xeForm.renderVN = renderVN
1116
+
1117
+ return $xeForm
1118
+ },
1119
+ render() {
1120
+ return this.renderVN()
1121
+ }
1122
+ })