vxe-pc-ui 3.14.6 → 3.14.7

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 (605) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +134 -134
  3. package/es/checkbox/src/button.js +25 -4
  4. package/es/checkbox/src/checkbox.js +25 -4
  5. package/es/checkbox/src/group.js +25 -3
  6. package/es/checkbox/style.css +6 -3
  7. package/es/checkbox/style.min.css +1 -1
  8. package/es/language/ar-EG.js +4 -0
  9. package/es/language/de-DE.js +4 -0
  10. package/es/language/en-US.js +4 -0
  11. package/es/language/es-ES.js +4 -0
  12. package/es/language/fr-FR.js +4 -0
  13. package/es/language/hu-HU.js +4 -0
  14. package/es/language/hy-AM.js +4 -0
  15. package/es/language/id-ID.js +4 -0
  16. package/es/language/it-IT.js +4 -0
  17. package/es/language/ja-JP.js +4 -0
  18. package/es/language/ko-KR.js +4 -0
  19. package/es/language/ms-MY.js +4 -0
  20. package/es/language/nb-NO.js +4 -0
  21. package/es/language/pt-BR.js +4 -0
  22. package/es/language/ru-RU.js +4 -0
  23. package/es/language/th-TH.js +4 -0
  24. package/es/language/ug-CN.js +4 -0
  25. package/es/language/uk-UA.js +4 -0
  26. package/es/language/uz-UZ.js +4 -0
  27. package/es/language/vi-VN.js +4 -0
  28. package/es/language/zh-CHT.js +4 -0
  29. package/es/language/zh-CN.js +4 -0
  30. package/es/radio/src/button.js +26 -5
  31. package/es/radio/src/group.js +19 -2
  32. package/es/radio/src/radio.js +26 -5
  33. package/es/radio/style.css +5 -3
  34. package/es/radio/style.min.css +1 -1
  35. package/es/style.css +1 -1
  36. package/es/style.min.css +1 -1
  37. package/es/switch/src/switch.js +19 -11
  38. package/es/tree/style.css +11 -6
  39. package/es/tree/style.min.css +1 -1
  40. package/es/ui/index.js +1 -1
  41. package/es/ui/src/log.js +1 -1
  42. package/es/vxe-checkbox/style.css +6 -3
  43. package/es/vxe-checkbox/style.min.css +1 -1
  44. package/es/vxe-radio/style.css +5 -3
  45. package/es/vxe-radio/style.min.css +1 -1
  46. package/es/vxe-tree/style.css +11 -6
  47. package/es/vxe-tree/style.min.css +1 -1
  48. package/lib/checkbox/src/button.js +20 -3
  49. package/lib/checkbox/src/button.min.js +1 -1
  50. package/lib/checkbox/src/checkbox.js +20 -3
  51. package/lib/checkbox/src/checkbox.min.js +1 -1
  52. package/lib/checkbox/src/group.js +24 -2
  53. package/lib/checkbox/src/group.min.js +1 -1
  54. package/lib/checkbox/style/style.css +6 -3
  55. package/lib/checkbox/style/style.min.css +1 -1
  56. package/lib/index.umd.js +8817 -8594
  57. package/lib/index.umd.min.js +1 -1
  58. package/lib/language/ar-EG.js +4 -0
  59. package/lib/language/ar-EG.min.js +1 -1
  60. package/lib/language/ar-EG.umd.js +4 -0
  61. package/lib/language/de-DE.js +4 -0
  62. package/lib/language/de-DE.min.js +1 -1
  63. package/lib/language/de-DE.umd.js +4 -0
  64. package/lib/language/en-US.js +4 -0
  65. package/lib/language/en-US.min.js +1 -1
  66. package/lib/language/en-US.umd.js +4 -0
  67. package/lib/language/es-ES.js +4 -0
  68. package/lib/language/es-ES.min.js +1 -1
  69. package/lib/language/es-ES.umd.js +4 -0
  70. package/lib/language/fr-FR.js +4 -0
  71. package/lib/language/fr-FR.min.js +1 -1
  72. package/lib/language/fr-FR.umd.js +4 -0
  73. package/lib/language/hu-HU.js +4 -0
  74. package/lib/language/hu-HU.min.js +1 -1
  75. package/lib/language/hu-HU.umd.js +4 -0
  76. package/lib/language/hy-AM.js +4 -0
  77. package/lib/language/hy-AM.min.js +1 -1
  78. package/lib/language/hy-AM.umd.js +4 -0
  79. package/lib/language/id-ID.js +4 -0
  80. package/lib/language/id-ID.min.js +1 -1
  81. package/lib/language/id-ID.umd.js +4 -0
  82. package/lib/language/it-IT.js +4 -0
  83. package/lib/language/it-IT.min.js +1 -1
  84. package/lib/language/it-IT.umd.js +4 -0
  85. package/lib/language/ja-JP.js +4 -0
  86. package/lib/language/ja-JP.min.js +1 -1
  87. package/lib/language/ja-JP.umd.js +4 -0
  88. package/lib/language/ko-KR.js +4 -0
  89. package/lib/language/ko-KR.min.js +1 -1
  90. package/lib/language/ko-KR.umd.js +4 -0
  91. package/lib/language/ms-MY.js +4 -0
  92. package/lib/language/ms-MY.min.js +1 -1
  93. package/lib/language/ms-MY.umd.js +4 -0
  94. package/lib/language/nb-NO.js +4 -0
  95. package/lib/language/nb-NO.min.js +1 -1
  96. package/lib/language/nb-NO.umd.js +4 -0
  97. package/lib/language/pt-BR.js +4 -0
  98. package/lib/language/pt-BR.min.js +1 -1
  99. package/lib/language/pt-BR.umd.js +4 -0
  100. package/lib/language/ru-RU.js +4 -0
  101. package/lib/language/ru-RU.min.js +1 -1
  102. package/lib/language/ru-RU.umd.js +4 -0
  103. package/lib/language/th-TH.js +4 -0
  104. package/lib/language/th-TH.min.js +1 -1
  105. package/lib/language/th-TH.umd.js +4 -0
  106. package/lib/language/ug-CN.js +4 -0
  107. package/lib/language/ug-CN.min.js +1 -1
  108. package/lib/language/ug-CN.umd.js +4 -0
  109. package/lib/language/uk-UA.js +4 -0
  110. package/lib/language/uk-UA.min.js +1 -1
  111. package/lib/language/uk-UA.umd.js +4 -0
  112. package/lib/language/uz-UZ.js +4 -0
  113. package/lib/language/uz-UZ.min.js +1 -1
  114. package/lib/language/uz-UZ.umd.js +4 -0
  115. package/lib/language/vi-VN.js +4 -0
  116. package/lib/language/vi-VN.min.js +1 -1
  117. package/lib/language/vi-VN.umd.js +4 -0
  118. package/lib/language/zh-CHT.js +4 -0
  119. package/lib/language/zh-CHT.min.js +1 -1
  120. package/lib/language/zh-CHT.umd.js +4 -0
  121. package/lib/language/zh-CN.js +4 -0
  122. package/lib/language/zh-CN.min.js +1 -1
  123. package/lib/language/zh-CN.umd.js +4 -0
  124. package/lib/radio/src/button.js +20 -3
  125. package/lib/radio/src/button.min.js +1 -1
  126. package/lib/radio/src/group.js +18 -1
  127. package/lib/radio/src/group.min.js +1 -1
  128. package/lib/radio/src/radio.js +20 -3
  129. package/lib/radio/src/radio.min.js +1 -1
  130. package/lib/radio/style/style.css +5 -3
  131. package/lib/radio/style/style.min.css +1 -1
  132. package/lib/style.css +1 -1
  133. package/lib/style.min.css +1 -1
  134. package/lib/switch/src/switch.js +15 -10
  135. package/lib/switch/src/switch.min.js +1 -1
  136. package/lib/tree/style/style.css +11 -6
  137. package/lib/tree/style/style.min.css +1 -1
  138. package/lib/ui/index.js +1 -1
  139. package/lib/ui/index.min.js +1 -1
  140. package/lib/ui/src/log.js +1 -1
  141. package/lib/ui/src/log.min.js +1 -1
  142. package/lib/vxe-checkbox/style/style.css +6 -3
  143. package/lib/vxe-checkbox/style/style.min.css +1 -1
  144. package/lib/vxe-radio/style/style.css +5 -3
  145. package/lib/vxe-radio/style/style.min.css +1 -1
  146. package/lib/vxe-tree/style/style.css +11 -6
  147. package/lib/vxe-tree/style/style.min.css +1 -1
  148. package/package.json +89 -89
  149. package/packages/alert/index.ts +16 -16
  150. package/packages/alert/src/alert.ts +106 -106
  151. package/packages/anchor/index.ts +16 -16
  152. package/packages/anchor/src/anchor-link.ts +158 -158
  153. package/packages/anchor/src/anchor.ts +267 -267
  154. package/packages/anchor/src/util.ts +23 -23
  155. package/packages/anchor-link/index.ts +16 -16
  156. package/packages/avatar/index.ts +16 -16
  157. package/packages/avatar/src/avatar.ts +141 -141
  158. package/packages/backtop/index.ts +16 -16
  159. package/packages/backtop/src/backtop.ts +330 -330
  160. package/packages/badge/index.ts +16 -16
  161. package/packages/badge/src/badge.ts +87 -87
  162. package/packages/breadcrumb/index.ts +16 -16
  163. package/packages/breadcrumb/src/breadcrumb-item.ts +118 -118
  164. package/packages/breadcrumb/src/breadcrumb.ts +89 -89
  165. package/packages/breadcrumb-item/index.ts +16 -16
  166. package/packages/button/index.ts +16 -16
  167. package/packages/button/src/button-group.ts +113 -113
  168. package/packages/button/src/button.ts +956 -956
  169. package/packages/button-group/index.ts +16 -16
  170. package/packages/calendar/index.ts +16 -16
  171. package/packages/calendar/src/calendar.ts +1527 -1527
  172. package/packages/card/index.ts +16 -16
  173. package/packages/card/src/card.ts +162 -162
  174. package/packages/carousel/index.ts +16 -16
  175. package/packages/carousel/src/carousel-item.ts +117 -117
  176. package/packages/carousel/src/carousel.ts +460 -460
  177. package/packages/carousel/src/util.ts +21 -21
  178. package/packages/carousel-item/index.ts +16 -16
  179. package/packages/cascader/index.ts +16 -16
  180. package/packages/cascader/src/cascader.ts +943 -943
  181. package/packages/checkbox/index.ts +16 -16
  182. package/packages/checkbox/src/button.ts +206 -185
  183. package/packages/checkbox/src/checkbox.ts +211 -189
  184. package/packages/checkbox/src/group.ts +282 -259
  185. package/packages/checkbox-button/index.ts +16 -16
  186. package/packages/checkbox-group/index.ts +16 -16
  187. package/packages/col/index.ts +16 -16
  188. package/packages/collapse/index.ts +16 -16
  189. package/packages/collapse/src/collapse-pane.ts +136 -136
  190. package/packages/collapse/src/collapse.ts +259 -259
  191. package/packages/collapse/src/util.ts +21 -21
  192. package/packages/collapse-pane/index.ts +16 -16
  193. package/packages/color-picker/index.ts +16 -16
  194. package/packages/color-picker/src/color-picker.ts +1286 -1286
  195. package/packages/color-picker/src/util.ts +198 -198
  196. package/packages/components.ts +307 -307
  197. package/packages/context-menu/index.ts +54 -54
  198. package/packages/context-menu/src/context-menu.ts +727 -727
  199. package/packages/countdown/index.ts +16 -16
  200. package/packages/countdown/src/countdown.ts +276 -276
  201. package/packages/date-panel/index.ts +16 -16
  202. package/packages/date-panel/src/date-panel.ts +2024 -2024
  203. package/packages/date-panel/src/util.ts +244 -244
  204. package/packages/date-picker/index.ts +17 -17
  205. package/packages/date-picker/src/date-picker.ts +1249 -1249
  206. package/packages/date-range-picker/index.ts +16 -16
  207. package/packages/date-range-picker/src/date-range-picker.ts +1480 -1480
  208. package/packages/drawer/index.ts +87 -87
  209. package/packages/drawer/src/drawer.ts +767 -767
  210. package/packages/dynamics/index.ts +127 -127
  211. package/packages/empty/index.ts +16 -16
  212. package/packages/empty/src/empty.ts +80 -80
  213. package/packages/form/index.ts +16 -16
  214. package/packages/form/render/index.ts +617 -617
  215. package/packages/form/src/form-config-item.ts +84 -84
  216. package/packages/form/src/form-group.ts +125 -125
  217. package/packages/form/src/form-item.ts +217 -217
  218. package/packages/form/src/form.ts +1032 -1032
  219. package/packages/form/src/itemInfo.ts +80 -80
  220. package/packages/form/src/render.ts +398 -398
  221. package/packages/form/src/util.ts +92 -92
  222. package/packages/form-gather/index.ts +18 -18
  223. package/packages/form-group/index.ts +16 -16
  224. package/packages/form-item/index.ts +16 -16
  225. package/packages/icon/index.ts +16 -16
  226. package/packages/icon/src/icon.ts +75 -75
  227. package/packages/icon-picker/index.ts +16 -16
  228. package/packages/icon-picker/src/icon-picker.ts +753 -753
  229. package/packages/image/index.ts +16 -16
  230. package/packages/image/src/group.ts +162 -162
  231. package/packages/image/src/image.ts +303 -303
  232. package/packages/image/src/preview.ts +737 -737
  233. package/packages/image/src/util.ts +62 -62
  234. package/packages/image-group/index.ts +16 -16
  235. package/packages/image-preview/index.ts +19 -19
  236. package/packages/index.ts +8 -8
  237. package/packages/input/index.ts +16 -16
  238. package/packages/input/src/input.ts +3187 -3187
  239. package/packages/language/ar-EG.ts +844 -840
  240. package/packages/language/de-DE.ts +844 -840
  241. package/packages/language/en-US.ts +844 -840
  242. package/packages/language/es-ES.ts +844 -840
  243. package/packages/language/fr-FR.ts +844 -840
  244. package/packages/language/hu-HU.ts +844 -840
  245. package/packages/language/hy-AM.ts +844 -840
  246. package/packages/language/id-ID.ts +844 -840
  247. package/packages/language/it-IT.ts +844 -840
  248. package/packages/language/ja-JP.ts +844 -840
  249. package/packages/language/ko-KR.ts +844 -840
  250. package/packages/language/ms-MY.ts +844 -840
  251. package/packages/language/nb-NO.ts +844 -840
  252. package/packages/language/pt-BR.ts +844 -840
  253. package/packages/language/ru-RU.ts +844 -840
  254. package/packages/language/th-TH.ts +844 -840
  255. package/packages/language/ug-CN.ts +844 -840
  256. package/packages/language/uk-UA.ts +844 -840
  257. package/packages/language/uz-UZ.ts +844 -840
  258. package/packages/language/vi-VN.ts +844 -840
  259. package/packages/language/zh-CHT.ts +844 -840
  260. package/packages/language/zh-CN.ts +844 -840
  261. package/packages/language/zh-HK.ts +3 -3
  262. package/packages/language/zh-MO.ts +3 -3
  263. package/packages/language/zh-TC.ts +3 -3
  264. package/packages/language/zh-TW.ts +3 -3
  265. package/packages/layout-aside/index.ts +16 -16
  266. package/packages/layout-aside/src/layout-aside.ts +115 -115
  267. package/packages/layout-body/index.ts +16 -16
  268. package/packages/layout-body/src/layout-body.ts +137 -137
  269. package/packages/layout-container/index.ts +16 -16
  270. package/packages/layout-container/src/layout-container.ts +65 -65
  271. package/packages/layout-footer/index.ts +16 -16
  272. package/packages/layout-footer/src/layout-footer.ts +53 -53
  273. package/packages/layout-header/index.ts +16 -16
  274. package/packages/layout-header/src/layout-header.ts +49 -49
  275. package/packages/link/index.ts +16 -16
  276. package/packages/link/src/link.ts +153 -153
  277. package/packages/list/index.ts +16 -16
  278. package/packages/list/src/list.ts +492 -492
  279. package/packages/loading/index.ts +34 -34
  280. package/packages/loading/src/loading.ts +162 -162
  281. package/packages/mention/index.ts +16 -16
  282. package/packages/mention/src/mention.ts +54 -54
  283. package/packages/menu/index.ts +16 -16
  284. package/packages/menu/src/menu.ts +632 -632
  285. package/packages/modal/index.ts +150 -150
  286. package/packages/modal/src/modal.ts +1668 -1668
  287. package/packages/notice-bar/index.ts +16 -16
  288. package/packages/notice-bar/src/notice-bar.ts +182 -182
  289. package/packages/number-input/index.ts +16 -16
  290. package/packages/number-input/src/number-input.ts +1255 -1255
  291. package/packages/number-input/src/util.ts +12 -12
  292. package/packages/optgroup/index.ts +16 -16
  293. package/packages/option/index.ts +16 -16
  294. package/packages/pager/index.ts +16 -16
  295. package/packages/pager/src/pager.ts +913 -913
  296. package/packages/password-input/index.ts +16 -16
  297. package/packages/password-input/src/password-input.ts +466 -466
  298. package/packages/print/index.ts +18 -18
  299. package/packages/print/src/page-break.ts +78 -78
  300. package/packages/print/src/print.ts +266 -266
  301. package/packages/print/src/util.ts +284 -284
  302. package/packages/print-page-break/index.ts +14 -14
  303. package/packages/pulldown/index.ts +16 -16
  304. package/packages/pulldown/src/pulldown.ts +533 -533
  305. package/packages/radio/index.ts +16 -16
  306. package/packages/radio/src/button.ts +242 -221
  307. package/packages/radio/src/group.ts +270 -252
  308. package/packages/radio/src/radio.ts +249 -228
  309. package/packages/radio-button/index.ts +16 -16
  310. package/packages/radio-group/index.ts +16 -16
  311. package/packages/rate/index.ts +16 -16
  312. package/packages/rate/src/rate.ts +199 -199
  313. package/packages/result/index.ts +16 -16
  314. package/packages/result/src/result.ts +93 -93
  315. package/packages/row/index.ts +16 -16
  316. package/packages/row/src/col.ts +130 -130
  317. package/packages/row/src/row.ts +106 -106
  318. package/packages/segmented/index.ts +16 -16
  319. package/packages/segmented/src/segmented.ts +281 -281
  320. package/packages/select/index.ts +16 -16
  321. package/packages/select/src/optgroup.ts +107 -107
  322. package/packages/select/src/option-info.ts +20 -20
  323. package/packages/select/src/option.ts +103 -103
  324. package/packages/select/src/select.ts +2001 -2001
  325. package/packages/select/src/util.ts +47 -47
  326. package/packages/slider/index.ts +16 -16
  327. package/packages/slider/src/slider.ts +332 -332
  328. package/packages/split/index.ts +16 -16
  329. package/packages/split-pane/index.ts +17 -17
  330. package/packages/splitter/index.ts +16 -16
  331. package/packages/splitter/src/splitter-panel.ts +171 -171
  332. package/packages/splitter/src/splitter.ts +1032 -1032
  333. package/packages/splitter/src/util.ts +21 -21
  334. package/packages/splitter-panel/index.ts +16 -16
  335. package/packages/steps/index.ts +16 -16
  336. package/packages/steps/src/steps.ts +57 -57
  337. package/packages/switch/index.ts +16 -16
  338. package/packages/switch/src/switch.ts +287 -279
  339. package/packages/tab-pane/index.ts +16 -16
  340. package/packages/table-select/index.ts +16 -16
  341. package/packages/table-select/src/table-select.ts +904 -904
  342. package/packages/tabs/index.ts +16 -16
  343. package/packages/tabs/src/tab-pane.ts +137 -137
  344. package/packages/tabs/src/tabs.ts +1014 -1014
  345. package/packages/tabs/src/util.ts +21 -21
  346. package/packages/tag/index.ts +16 -16
  347. package/packages/tag/src/tag.ts +195 -195
  348. package/packages/text/index.ts +16 -16
  349. package/packages/text/src/text.ts +267 -267
  350. package/packages/text-ellipsis/index.ts +16 -16
  351. package/packages/text-ellipsis/src/text-ellipsis.ts +291 -291
  352. package/packages/textarea/index.ts +16 -16
  353. package/packages/textarea/src/textarea.ts +436 -436
  354. package/packages/timeline/index.ts +16 -16
  355. package/packages/timeline/src/timeline-item.ts +41 -41
  356. package/packages/timeline/src/timeline.ts +54 -54
  357. package/packages/timeline-item/index.ts +16 -16
  358. package/packages/tip/index.ts +19 -19
  359. package/packages/tip/src/tip.ts +112 -112
  360. package/packages/tooltip/index.ts +16 -16
  361. package/packages/tooltip/src/tooltip.ts +669 -669
  362. package/packages/tour/index.ts +16 -16
  363. package/packages/tour/src/tour.ts +54 -54
  364. package/packages/tree/index.ts +16 -16
  365. package/packages/tree/src/store.ts +15 -15
  366. package/packages/tree/src/tree.ts +3122 -3122
  367. package/packages/tree/src/util.ts +44 -44
  368. package/packages/tree-select/index.ts +16 -16
  369. package/packages/tree-select/src/tree-select.ts +1118 -1118
  370. package/packages/ui/index.ts +697 -697
  371. package/packages/ui/src/anime.ts +52 -52
  372. package/packages/ui/src/comp.ts +3 -3
  373. package/packages/ui/src/dom.ts +279 -279
  374. package/packages/ui/src/log.ts +6 -6
  375. package/packages/ui/src/utils.ts +49 -49
  376. package/packages/ui/src/vn.ts +60 -60
  377. package/packages/upload/index.ts +20 -20
  378. package/packages/upload/src/upload.ts +2129 -2129
  379. package/packages/upload/src/util.ts +109 -109
  380. package/packages/vxe-u-i/index.ts +4 -4
  381. package/packages/watermark/index.ts +31 -31
  382. package/packages/watermark/src/util.ts +176 -176
  383. package/packages/watermark/src/watermark.ts +166 -166
  384. package/styles/all.scss +90 -90
  385. package/styles/base.scss +16 -16
  386. package/styles/components/alert.scss +101 -101
  387. package/styles/components/anchor.scss +44 -44
  388. package/styles/components/avatar.scss +115 -115
  389. package/styles/components/backtop.scss +82 -82
  390. package/styles/components/badge.scss +45 -45
  391. package/styles/components/breadcrumb.scss +29 -29
  392. package/styles/components/button-group.scss +30 -30
  393. package/styles/components/button.scss +415 -415
  394. package/styles/components/calendar.scss +471 -471
  395. package/styles/components/card.scss +121 -121
  396. package/styles/components/carousel.scss +184 -184
  397. package/styles/components/cascader.scss +140 -140
  398. package/styles/components/checkbox-button.scss +57 -57
  399. package/styles/components/checkbox.scss +81 -81
  400. package/styles/components/collapse.scss +56 -56
  401. package/styles/components/color-picker.scss +409 -409
  402. package/styles/components/context-menu.scss +102 -102
  403. package/styles/components/countdown.scss +35 -35
  404. package/styles/components/date-panel.scss +505 -505
  405. package/styles/components/date-picker.scss +247 -247
  406. package/styles/components/date-range-picker.scss +252 -252
  407. package/styles/components/drawer.scss +298 -298
  408. package/styles/components/empty.scss +79 -79
  409. package/styles/components/form.scss +668 -668
  410. package/styles/components/icon-picker.scss +211 -211
  411. package/styles/components/icon.scss +1048 -1048
  412. package/styles/components/image-group.scss +2 -2
  413. package/styles/components/image-preview.scss +215 -215
  414. package/styles/components/image.scss +16 -16
  415. package/styles/components/input.scss +846 -846
  416. package/styles/components/layout-aside.scss +22 -22
  417. package/styles/components/layout-body.scss +14 -14
  418. package/styles/components/layout-container.scss +13 -13
  419. package/styles/components/layout-footer.scss +14 -14
  420. package/styles/components/layout-header.scss +11 -11
  421. package/styles/components/link.scss +115 -115
  422. package/styles/components/list.scss +40 -40
  423. package/styles/components/loading.scss +137 -137
  424. package/styles/components/menu.scss +150 -150
  425. package/styles/components/modal.scss +480 -480
  426. package/styles/components/notice-bar.scss +91 -91
  427. package/styles/components/number-input.scss +283 -283
  428. package/styles/components/old-icon.scss +4 -4
  429. package/styles/components/pager.scss +282 -282
  430. package/styles/components/password-input.scss +374 -374
  431. package/styles/components/print.scss +3 -3
  432. package/styles/components/pulldown.scss +75 -75
  433. package/styles/components/radio-button.scss +57 -57
  434. package/styles/components/radio.scss +79 -79
  435. package/styles/components/rate.scss +76 -76
  436. package/styles/components/result.scss +91 -91
  437. package/styles/components/row.scss +69 -69
  438. package/styles/components/segmented.scss +215 -215
  439. package/styles/components/select.scss +244 -244
  440. package/styles/components/slider.scss +139 -139
  441. package/styles/components/split.scss +1 -1
  442. package/styles/components/splitter.scss +318 -318
  443. package/styles/components/switch.scss +128 -128
  444. package/styles/components/table-select.scss +105 -105
  445. package/styles/components/tabs.scss +745 -745
  446. package/styles/components/tag.scss +184 -184
  447. package/styles/components/text-ellipsis.scss +130 -130
  448. package/styles/components/text.scss +123 -123
  449. package/styles/components/textarea.scss +106 -106
  450. package/styles/components/tip.scss +97 -97
  451. package/styles/components/tooltip.scss +141 -141
  452. package/styles/components/tree-select.scss +166 -166
  453. package/styles/components/tree.scss +294 -294
  454. package/styles/components/upload.scss +497 -497
  455. package/styles/components/watermark.scss +26 -26
  456. package/styles/helpers/baseMixin.scss +104 -95
  457. package/styles/helpers/baseVar.scss +3 -3
  458. package/styles/helpers/placement.scss +38 -38
  459. package/styles/theme/base.scss +214 -214
  460. package/styles/theme/dark.scss +119 -119
  461. package/styles/theme/light.scss +118 -118
  462. package/styles/variable.scss +111 -111
  463. package/types/all.d.ts +328 -328
  464. package/types/components/alert.d.ts +80 -80
  465. package/types/components/anchor-link.d.ts +84 -84
  466. package/types/components/anchor.d.ts +84 -84
  467. package/types/components/avatar.d.ts +81 -81
  468. package/types/components/backtop.d.ts +115 -115
  469. package/types/components/badge.d.ts +69 -69
  470. package/types/components/breadcrumb-item.d.ts +73 -73
  471. package/types/components/breadcrumb.d.ts +80 -80
  472. package/types/components/button-group.d.ts +113 -113
  473. package/types/components/button.d.ts +314 -314
  474. package/types/components/calendar.d.ts +254 -254
  475. package/types/components/card.d.ts +86 -86
  476. package/types/components/carousel-item.d.ts +68 -68
  477. package/types/components/carousel.d.ts +126 -126
  478. package/types/components/cascader.d.ts +250 -250
  479. package/types/components/checkbox-button.d.ts +93 -93
  480. package/types/components/checkbox-group.d.ts +138 -135
  481. package/types/components/checkbox.d.ts +115 -115
  482. package/types/components/col.d.ts +73 -73
  483. package/types/components/colgroup.d.ts +131 -131
  484. package/types/components/collapse-pane.d.ts +82 -82
  485. package/types/components/collapse.d.ts +115 -115
  486. package/types/components/color-picker.d.ts +164 -164
  487. package/types/components/column.d.ts +852 -852
  488. package/types/components/context-menu.d.ts +301 -301
  489. package/types/components/countdown.d.ts +99 -99
  490. package/types/components/date-panel.d.ts +269 -269
  491. package/types/components/date-picker.d.ts +322 -322
  492. package/types/components/date-range-picker.d.ts +336 -336
  493. package/types/components/drawer.d.ts +295 -295
  494. package/types/components/empty.d.ts +71 -71
  495. package/types/components/flow-design.d.ts +78 -78
  496. package/types/components/flow-view.d.ts +78 -78
  497. package/types/components/form-design.d.ts +364 -364
  498. package/types/components/form-gather.d.ts +72 -72
  499. package/types/components/form-group.d.ts +63 -63
  500. package/types/components/form-item.d.ts +405 -405
  501. package/types/components/form-view.d.ts +175 -175
  502. package/types/components/form.d.ts +463 -463
  503. package/types/components/gantt-module/gantt-view.d.ts +171 -171
  504. package/types/components/gantt-module/index.d.ts +1 -1
  505. package/types/components/gantt-plugins/extend-gantt-chart.d.ts +132 -132
  506. package/types/components/gantt-plugins/index.d.ts +1 -1
  507. package/types/components/gantt.d.ts +1201 -1201
  508. package/types/components/grid.d.ts +1038 -1038
  509. package/types/components/icon-picker.d.ts +185 -185
  510. package/types/components/icon.d.ts +80 -80
  511. package/types/components/image-group.d.ts +120 -120
  512. package/types/components/image-preview.d.ts +159 -159
  513. package/types/components/image.d.ts +166 -166
  514. package/types/components/input.d.ts +425 -425
  515. package/types/components/layout-aside.d.ts +73 -73
  516. package/types/components/layout-body.d.ts +84 -84
  517. package/types/components/layout-container.d.ts +66 -66
  518. package/types/components/layout-footer.d.ts +66 -66
  519. package/types/components/layout-header.d.ts +64 -64
  520. package/types/components/link.d.ts +104 -104
  521. package/types/components/list-design.d.ts +177 -177
  522. package/types/components/list-view.d.ts +190 -190
  523. package/types/components/list.d.ts +196 -196
  524. package/types/components/loading.d.ts +96 -96
  525. package/types/components/mention.d.ts +70 -70
  526. package/types/components/menu.d.ts +203 -203
  527. package/types/components/modal.d.ts +540 -540
  528. package/types/components/notice-bar.d.ts +95 -95
  529. package/types/components/number-input.d.ts +300 -300
  530. package/types/components/optgroup.d.ts +81 -81
  531. package/types/components/option.d.ts +95 -95
  532. package/types/components/pager.d.ts +322 -322
  533. package/types/components/password-input.d.ts +129 -129
  534. package/types/components/print-page-break.d.ts +62 -62
  535. package/types/components/print.d.ts +199 -199
  536. package/types/components/pulldown.d.ts +226 -226
  537. package/types/components/radio-button.d.ts +104 -104
  538. package/types/components/radio-group.d.ts +139 -136
  539. package/types/components/radio.d.ts +121 -121
  540. package/types/components/rate.d.ts +75 -75
  541. package/types/components/result.d.ts +77 -77
  542. package/types/components/row.d.ts +72 -72
  543. package/types/components/segmented.d.ts +117 -117
  544. package/types/components/select.d.ts +519 -519
  545. package/types/components/slider.d.ts +117 -117
  546. package/types/components/split-pane.d.ts +135 -135
  547. package/types/components/split.d.ts +318 -318
  548. package/types/components/splitter-panel.d.ts +98 -98
  549. package/types/components/splitter.d.ts +283 -283
  550. package/types/components/steps.d.ts +61 -61
  551. package/types/components/switch.d.ts +124 -124
  552. package/types/components/tab-pane.d.ts +107 -107
  553. package/types/components/table-module/custom.d.ts +115 -115
  554. package/types/components/table-module/edit.d.ts +245 -245
  555. package/types/components/table-module/export.d.ts +96 -96
  556. package/types/components/table-module/filter.d.ts +140 -140
  557. package/types/components/table-module/index.d.ts +7 -7
  558. package/types/components/table-module/keyboard.d.ts +26 -26
  559. package/types/components/table-module/menu.d.ts +26 -26
  560. package/types/components/table-module/validator.d.ts +53 -53
  561. package/types/components/table-plugins/extend-cell-area.d.ts +768 -768
  562. package/types/components/table-plugins/extend-pivot-table.d.ts +68 -68
  563. package/types/components/table-plugins/filters-combination.d.ts +15 -15
  564. package/types/components/table-plugins/filters-complex-input.d.ts +9 -9
  565. package/types/components/table-plugins/index.d.ts +4 -4
  566. package/types/components/table-select.d.ts +216 -216
  567. package/types/components/table.d.ts +7496 -7496
  568. package/types/components/tabs.d.ts +324 -324
  569. package/types/components/tag.d.ts +107 -107
  570. package/types/components/text-ellipsis.d.ts +105 -105
  571. package/types/components/text.d.ts +115 -115
  572. package/types/components/textarea.d.ts +237 -237
  573. package/types/components/timeline-item.d.ts +68 -68
  574. package/types/components/timeline.d.ts +70 -70
  575. package/types/components/tip.d.ts +76 -76
  576. package/types/components/toolbar.d.ts +329 -329
  577. package/types/components/tooltip.d.ts +169 -169
  578. package/types/components/tour.d.ts +70 -70
  579. package/types/components/tree-select.d.ts +299 -299
  580. package/types/components/tree.d.ts +836 -836
  581. package/types/components/upload.d.ts +432 -432
  582. package/types/components/watermark.d.ts +113 -113
  583. package/types/index.d.ts +4 -4
  584. package/types/ui/commands.d.ts +57 -57
  585. package/types/ui/formats.d.ts +62 -62
  586. package/types/ui/global-config.d.ts +254 -254
  587. package/types/ui/global-icon.d.ts +292 -292
  588. package/types/ui/hooks.d.ts +11 -11
  589. package/types/ui/index.d.ts +95 -95
  590. package/types/ui/interceptor.d.ts +54 -54
  591. package/types/ui/menus.d.ts +77 -77
  592. package/types/ui/renderer.d.ts +1042 -1042
  593. package/types/ui/validators.d.ts +38 -38
  594. /package/es/icon/{iconfont.1778317204332.ttf → iconfont.1778465052628.ttf} +0 -0
  595. /package/es/icon/{iconfont.1778317204332.woff → iconfont.1778465052628.woff} +0 -0
  596. /package/es/icon/{iconfont.1778317204332.woff2 → iconfont.1778465052628.woff2} +0 -0
  597. /package/es/{iconfont.1778317204332.ttf → iconfont.1778465052628.ttf} +0 -0
  598. /package/es/{iconfont.1778317204332.woff → iconfont.1778465052628.woff} +0 -0
  599. /package/es/{iconfont.1778317204332.woff2 → iconfont.1778465052628.woff2} +0 -0
  600. /package/lib/icon/style/{iconfont.1778317204332.ttf → iconfont.1778465052628.ttf} +0 -0
  601. /package/lib/icon/style/{iconfont.1778317204332.woff → iconfont.1778465052628.woff} +0 -0
  602. /package/lib/icon/style/{iconfont.1778317204332.woff2 → iconfont.1778465052628.woff2} +0 -0
  603. /package/lib/{iconfont.1778317204332.ttf → iconfont.1778465052628.ttf} +0 -0
  604. /package/lib/{iconfont.1778317204332.woff → iconfont.1778465052628.woff} +0 -0
  605. /package/lib/{iconfont.1778317204332.woff2 → iconfont.1778465052628.woff2} +0 -0
@@ -1,2129 +1,2129 @@
1
- import { PropType, CreateElement, VNode } from 'vue'
2
- import { defineVxeComponent } from '../../ui/src/comp'
3
- import XEUtils from 'xe-utils'
4
- import { VxeUI, getConfig, getI18n, getIcon, globalMixins, createEvent, globalEvents, renderEmptyElement } from '../../ui'
5
- import { getSlotVNs } from '../../ui/src/vn'
6
- import { errLog, warnLog } from '../../ui/src/log'
7
- import { initTpImg, getTpImg, getEventTargetNode, toCssUnit } from '../../ui/src/dom'
8
- import { readLocalFile } from './util'
9
- import VxeButtonComponent from '../../button/src/button'
10
-
11
- import type { VxeUploadDefines, VxeUploadConstructor, VxeUploadPropTypes, UploadReactData, UploadInternalData, VxeUploadEmits, VxeComponentSizeType, VxeFormDefines, VxeFormConstructor, VxeFormPrivateMethods, ValueOf, VxeComponentEventParams } from '../../../types'
12
- import type { VxeTableConstructor, VxeTablePrivateMethods } from '../../../types/components/table'
13
-
14
- function getUniqueKey () {
15
- return XEUtils.uniqueId()
16
- }
17
-
18
- function handleTransferFiles (items: DataTransferItemList) {
19
- const files: File[] = []
20
- XEUtils.arrayEach(items, item => {
21
- const file = item.getAsFile()
22
- if (file) {
23
- files.push(file)
24
- }
25
- })
26
- return files
27
- }
28
-
29
- function showDropTip ($xeUpload: VxeUploadConstructor, evnt: DragEvent, dragEl: HTMLElement, dragPos: string) {
30
- const { xID } = $xeUpload
31
-
32
- const reactData = $xeUpload.reactData
33
-
34
- const { showMorePopup } = reactData
35
- const el = $xeUpload.$refs.refElem as HTMLDivElement
36
- const popupEl = document.getElementById(`refPopupElem${xID}`) as HTMLDivElement
37
- const wrapperEl = showMorePopup ? popupEl : el
38
- if (!wrapperEl) {
39
- return
40
- }
41
- const wrapperRect = wrapperEl.getBoundingClientRect()
42
- const ddLineEl = $xeUpload.$refs.refDragLineElem as HTMLDivElement
43
- const mdLineEl = document.getElementById(`refModalDragLineElem${xID}`) as HTMLDivElement
44
- const currDLineEl = showMorePopup ? mdLineEl : ddLineEl
45
- if (currDLineEl) {
46
- const dragRect = dragEl.getBoundingClientRect()
47
- currDLineEl.style.display = 'block'
48
- currDLineEl.style.top = `${Math.max(1, dragRect.y - wrapperRect.y)}px`
49
- currDLineEl.style.left = `${Math.max(1, dragRect.x - wrapperRect.x)}px`
50
- currDLineEl.style.height = `${dragRect.height}px`
51
- currDLineEl.style.width = `${dragRect.width - 1}px`
52
- currDLineEl.setAttribute('drag-pos', dragPos)
53
- }
54
- }
55
-
56
- function hideDropTip ($xeUpload: VxeUploadConstructor) {
57
- const { xID } = $xeUpload
58
-
59
- const ddLineEl = $xeUpload.$refs.refDragLineElem as HTMLDivElement
60
- const mdLineEl = document.getElementById(`refModalDragLineElem${xID}`) as HTMLDivElement
61
- if (ddLineEl) {
62
- ddLineEl.style.display = ''
63
- }
64
- if (mdLineEl) {
65
- mdLineEl.style.display = ''
66
- }
67
- }
68
-
69
- function createReactData (): UploadReactData {
70
- return {
71
- isDragUploadStatus: false,
72
- showMorePopup: false,
73
- isActivated: false,
74
- fileList: [],
75
- fileCacheMaps: {},
76
- isDragMove: false,
77
- dragIndex: -1,
78
- dragTipText: ''
79
- }
80
- }
81
-
82
- function createInternalData (): UploadInternalData {
83
- return {
84
- moreId: XEUtils.uniqueId('upload'),
85
- imagePreviewTypes: ['jpg', 'jpeg', 'png', 'gif'],
86
- prevDragIndex: -1
87
- // prevDragPos: ''
88
- }
89
- }
90
-
91
- export default /* define-vxe-component start */ defineVxeComponent({
92
- name: 'VxeUpload',
93
- model: {
94
- prop: 'value',
95
- event: 'modelValue'
96
- },
97
- mixins: [
98
- globalMixins.sizeMixin
99
- ],
100
- props: {
101
- value: [Array, String, Object] as PropType<VxeUploadPropTypes.ModelValue>,
102
- showList: {
103
- type: Boolean as PropType<VxeUploadPropTypes.ShowList>,
104
- default: () => getConfig().upload.showList
105
- },
106
- moreConfig: Object as PropType<VxeUploadPropTypes.MoreConfig>,
107
- readonly: {
108
- type: Boolean as PropType<VxeUploadPropTypes.Readonly>,
109
- default: null
110
- },
111
- disabled: {
112
- type: Boolean as PropType<VxeUploadPropTypes.Disabled>,
113
- default: null
114
- },
115
- autoSubmit: {
116
- type: Boolean as PropType<VxeUploadPropTypes.AutoSubmit>,
117
- default: () => getConfig().upload.autoSubmit
118
- },
119
- mode: {
120
- type: String as PropType<VxeUploadPropTypes.Mode>,
121
- default: () => getConfig().upload.mode
122
- },
123
- imageTypes: {
124
- type: Array as PropType<VxeUploadPropTypes.ImageTypes>,
125
- default: () => XEUtils.clone(getConfig().upload.imageTypes, true)
126
- },
127
- imageConfig: {
128
- type: Object as PropType<VxeUploadPropTypes.ImageConfig>,
129
- default: () => XEUtils.clone(getConfig().upload.imageConfig, true)
130
- },
131
- /**
132
- * 已废弃,被 image-config 替换
133
- * @deprecated
134
- */
135
- imageStyle: {
136
- type: Object as PropType<VxeUploadPropTypes.ImageStyle>,
137
- default: () => XEUtils.clone(getConfig().upload.imageStyle, true)
138
- },
139
- fileTypes: {
140
- type: Array as PropType<VxeUploadPropTypes.FileTypes>,
141
- default: () => XEUtils.clone(getConfig().upload.fileTypes, true)
142
- },
143
- dragSort: Boolean as PropType<VxeUploadPropTypes.DragSort>,
144
- dragToUpload: {
145
- type: Boolean as PropType<VxeUploadPropTypes.DragToUpload>,
146
- default: () => XEUtils.clone(getConfig().upload.dragToUpload, true)
147
- },
148
- dragPlaceholder: {
149
- type: String as PropType<VxeUploadPropTypes.DragPlaceholder>,
150
- default: () => getConfig().upload.dragPlaceholder
151
- },
152
- pasteToUpload: {
153
- type: Boolean as PropType<VxeUploadPropTypes.PasteToUpload>,
154
- default: () => XEUtils.clone(getConfig().upload.pasteToUpload, true)
155
- },
156
- keyField: String as PropType<VxeUploadPropTypes.KeyField>,
157
- singleMode: Boolean as PropType<VxeUploadPropTypes.SingleMode>,
158
- urlMode: Boolean as PropType<VxeUploadPropTypes.UrlMode>,
159
- urlArgs: {
160
- type: Boolean as PropType<VxeUploadPropTypes.UrlArgs>,
161
- default: () => getConfig().upload.urlArgs
162
- },
163
- multiple: Boolean as PropType<VxeUploadPropTypes.Multiple>,
164
- limitSize: {
165
- type: [String, Number] as PropType<VxeUploadPropTypes.LimitSize>,
166
- default: () => getConfig().upload.limitSize
167
- },
168
- showLimitSize: {
169
- type: Boolean as PropType<VxeUploadPropTypes.ShowLimitSize>,
170
- default: () => getConfig().upload.showLimitSize
171
- },
172
- limitSizeText: {
173
- type: [String, Number, Function] as PropType<VxeUploadPropTypes.LimitSizeText>,
174
- default: () => getConfig().upload.limitSizeText
175
- },
176
- limitCount: {
177
- type: [String, Number] as PropType<VxeUploadPropTypes.LimitCount>,
178
- default: () => getConfig().upload.limitCount
179
- },
180
- showLimitCount: {
181
- type: Boolean as PropType<VxeUploadPropTypes.ShowLimitCount>,
182
- default: () => getConfig().upload.showLimitCount
183
- },
184
- limitCountText: {
185
- type: [String, Number, Function] as PropType<VxeUploadPropTypes.LimitCountText>,
186
- default: () => getConfig().upload.limitCountText
187
- },
188
- nameField: {
189
- type: String as PropType<VxeUploadPropTypes.NameField>,
190
- default: () => getConfig().upload.nameField
191
- },
192
- typeField: {
193
- type: String as PropType<VxeUploadPropTypes.TypeField>,
194
- default: () => getConfig().upload.typeField
195
- },
196
- urlField: {
197
- type: String as PropType<VxeUploadPropTypes.UrlField>,
198
- default: () => getConfig().upload.urlField
199
- },
200
- sizeField: {
201
- type: String as PropType<VxeUploadPropTypes.SizeField>,
202
- default: () => getConfig().upload.sizeField
203
- },
204
- showErrorStatus: {
205
- type: Boolean as PropType<VxeUploadPropTypes.ShowErrorStatus>,
206
- default: () => getConfig().upload.showErrorStatus
207
- },
208
- showProgress: {
209
- type: Boolean as PropType<VxeUploadPropTypes.ShowProgress>,
210
- default: () => getConfig().upload.showProgress
211
- },
212
- progressText: {
213
- type: [String, Number, Function] as PropType<VxeUploadPropTypes.ProgressText>,
214
- default: () => getConfig().upload.progressText
215
- },
216
- previewImageConfig: Object as PropType<VxeUploadPropTypes.PreviewImageConfig>,
217
- showSubmitButton: Boolean as PropType<VxeUploadPropTypes.ShowSubmitButton>,
218
- autoHiddenButton: {
219
- type: Boolean as PropType<VxeUploadPropTypes.AutoHiddenButton>,
220
- default: () => getConfig().upload.autoHiddenButton
221
- },
222
- showUploadButton: {
223
- type: Boolean as PropType<VxeUploadPropTypes.ShowUploadButton>,
224
- default: () => getConfig().upload.showUploadButton
225
- },
226
- buttonText: {
227
- type: [String, Number, Function] as PropType<VxeUploadPropTypes.ButtonText>,
228
- default: () => getConfig().upload.buttonText
229
- },
230
- buttonIcon: {
231
- type: String as PropType<VxeUploadPropTypes.ButtonIcon>,
232
- default: () => getConfig().upload.buttonIcon
233
- },
234
- showButtonText: {
235
- type: Boolean as PropType<VxeUploadPropTypes.ShowButtonText>,
236
- default: () => getConfig().upload.showButtonText
237
- },
238
- showButtonIcon: {
239
- type: Boolean as PropType<VxeUploadPropTypes.ShowButtonIcon>,
240
- default: () => getConfig().upload.showButtonIcon
241
- },
242
- showRemoveButton: {
243
- type: Boolean as PropType<VxeUploadPropTypes.ShowRemoveButton>,
244
- default: () => getConfig().upload.showRemoveButton
245
- },
246
- showDownloadButton: {
247
- type: Boolean as PropType<VxeUploadPropTypes.ShowDownloadButton>,
248
- default: () => getConfig().upload.showDownloadButton
249
- },
250
- showPreview: {
251
- type: Boolean as PropType<VxeUploadPropTypes.ShowPreview>,
252
- default: () => getConfig().upload.showPreview
253
- },
254
- showTip: {
255
- type: Boolean as PropType<VxeUploadPropTypes.ShowTip>,
256
- default: () => getConfig().upload.showTip
257
- },
258
- maxSimultaneousUploads: {
259
- type: Number as PropType<VxeUploadPropTypes.MaxSimultaneousUploads>,
260
- default: () => getConfig().upload.maxSimultaneousUploads
261
- },
262
- tipText: [String, Number, Function] as PropType<VxeUploadPropTypes.TipText>,
263
- hintText: String as PropType<VxeUploadPropTypes.HintText>,
264
- previewMethod: Function as PropType<VxeUploadPropTypes.PreviewMethod>,
265
- beforeSelectMethod: Function as PropType<VxeUploadPropTypes.BeforeSelectMethod>,
266
- uploadMethod: Function as PropType<VxeUploadPropTypes.UploadMethod>,
267
- beforeRemoveMethod: Function as PropType<VxeUploadPropTypes.BeforeRemoveMethod>,
268
- removeMethod: Function as PropType<VxeUploadPropTypes.RemoveMethod>,
269
- beforeDownloadMethod: Function as PropType<VxeUploadPropTypes.BeforeDownloadMethod>,
270
- downloadMethod: Function as PropType<VxeUploadPropTypes.DownloadMethod>,
271
- getUrlMethod: Function as PropType<VxeUploadPropTypes.GetUrlMethod>,
272
- getThumbnailUrlMethod: Function as PropType<VxeUploadPropTypes.GetThumbnailUrlMethod>,
273
- size: {
274
- type: String as PropType<VxeUploadPropTypes.Size>,
275
- default: () => getConfig().upload.size || getConfig().size
276
- }
277
- },
278
- inject: {
279
- $xeForm: {
280
- default: null
281
- },
282
- formItemInfo: {
283
- from: 'xeFormItemInfo',
284
- default: null
285
- },
286
- $xeTable: {
287
- default: null
288
- }
289
- },
290
- data () {
291
- const xID = XEUtils.uniqueId()
292
- const reactData = createReactData()
293
- const internalData = createInternalData()
294
- return {
295
- xID,
296
- reactData,
297
- internalData
298
- }
299
- },
300
- computed: {
301
- ...({} as {
302
- computeSize(): VxeComponentSizeType
303
- $xeForm(): (VxeFormConstructor & VxeFormPrivateMethods) | null
304
- formItemInfo(): VxeFormDefines.ProvideItemInfo | null,
305
- $xeTable(): (VxeTableConstructor & VxeTablePrivateMethods) | null
306
- }),
307
- computeFormReadonly () {
308
- const $xeUpload = this
309
- const props = $xeUpload
310
- const $xeForm = $xeUpload.$xeForm
311
-
312
- const { readonly } = props
313
- if (readonly === null) {
314
- if ($xeForm) {
315
- return $xeForm.readonly
316
- }
317
- return false
318
- }
319
- return readonly
320
- },
321
- computeIsDisabled () {
322
- const $xeUpload = this
323
- const props = $xeUpload
324
- const $xeForm = $xeUpload.$xeForm
325
-
326
- const { disabled } = props
327
- if (disabled === null) {
328
- if ($xeForm) {
329
- return $xeForm.disabled
330
- }
331
- return false
332
- }
333
- return disabled
334
- },
335
- computeKeyField () {
336
- const $xeUpload = this
337
- const props = $xeUpload
338
-
339
- return props.keyField || '_X_KEY'
340
- },
341
- computeIsImage () {
342
- const $xeUpload = this
343
- const props = $xeUpload
344
-
345
- return props.mode === 'image'
346
- },
347
- computeNameProp () {
348
- const $xeUpload = this
349
- const props = $xeUpload
350
-
351
- return props.nameField || 'name'
352
- },
353
- computeTypeProp () {
354
- const $xeUpload = this
355
- const props = $xeUpload
356
-
357
- return props.typeField || 'type'
358
- },
359
- computeUrlProp () {
360
- const $xeUpload = this
361
- const props = $xeUpload
362
-
363
- return props.urlField || 'url'
364
- },
365
- computeSizeProp () {
366
- const $xeUpload = this
367
- const props = $xeUpload
368
-
369
- return props.sizeField || 'size'
370
- },
371
- computeLimitMaxSize () {
372
- const $xeUpload = this
373
- const props = $xeUpload
374
-
375
- return XEUtils.toNumber(props.limitSize) * 1024 * 1024
376
- },
377
- computeLimitMaxCount () {
378
- const $xeUpload = this
379
- const props = $xeUpload
380
-
381
- return props.multiple ? XEUtils.toNumber(props.limitCount) : 1
382
- },
383
- computePreviewImageOpts () {
384
- const $xeUpload = this
385
- const props = $xeUpload
386
-
387
- const { showDownloadButton } = props
388
- return Object.assign({
389
- showDownloadButton
390
- }, getConfig().upload.previewImageConfig, props.previewImageConfig)
391
- },
392
- computeOverCount () {
393
- const $xeUpload = this
394
- const props = $xeUpload
395
- const reactData = $xeUpload.reactData as UploadReactData
396
-
397
- const { multiple } = props
398
- const { fileList } = reactData
399
- const limitMaxCount = $xeUpload.computeLimitMaxCount as number
400
- if (multiple) {
401
- if (limitMaxCount) {
402
- return fileList.length >= limitMaxCount
403
- }
404
- return true
405
- }
406
- return fileList.length >= 1
407
- },
408
- computeLimitSizeUnit () {
409
- const $xeUpload = this
410
- const props = $xeUpload
411
-
412
- const limitSize = XEUtils.toNumber(props.limitSize)
413
- if (limitSize) {
414
- if (limitSize > 1048576) {
415
- return `${limitSize / 1048576}T`
416
- }
417
- if (limitSize > 1024) {
418
- return `${limitSize / 1024}G`
419
- }
420
- return `${limitSize}M`
421
- }
422
- return ''
423
- },
424
- computedShowTipText () {
425
- const $xeUpload = this
426
- const props = $xeUpload
427
-
428
- const { showTip, tipText } = props
429
- if (XEUtils.isBoolean(showTip)) {
430
- return showTip
431
- }
432
- const defShowTip = getConfig().upload.showTip
433
- if (XEUtils.isBoolean(defShowTip)) {
434
- return defShowTip
435
- }
436
- if (tipText) {
437
- return true
438
- }
439
- return false
440
- },
441
- computedDefTipText () {
442
- const $xeUpload = this
443
- const props = $xeUpload
444
-
445
- const { limitSize, fileTypes, multiple, limitCount } = props
446
- const tipText = props.tipText || props.hintText
447
- const isImage = $xeUpload.computeIsImage
448
- const limitSizeUnit = $xeUpload.computeLimitSizeUnit
449
- if (XEUtils.isString(tipText)) {
450
- return tipText
451
- }
452
- if (XEUtils.isFunction(tipText)) {
453
- return `${tipText({})}`
454
- }
455
- const defTips: string[] = []
456
- if (isImage) {
457
- if (multiple && limitCount) {
458
- defTips.push(getI18n('vxe.upload.imgCountHint', [limitCount]))
459
- }
460
- if (limitSize && limitSizeUnit) {
461
- defTips.push(getI18n('vxe.upload.imgSizeHint', [limitSizeUnit]))
462
- }
463
- } else {
464
- if (fileTypes && fileTypes.length) {
465
- defTips.push(getI18n('vxe.upload.fileTypeHint', [fileTypes.join('/')]))
466
- }
467
- if (limitSize && limitSizeUnit) {
468
- defTips.push(getI18n('vxe.upload.fileSizeHint', [limitSizeUnit]))
469
- }
470
- if (multiple && limitCount) {
471
- defTips.push(getI18n('vxe.upload.fileCountHint', [limitCount]))
472
- }
473
- }
474
- return defTips.join(getI18n('vxe.base.comma'))
475
- },
476
- computeImageOpts () {
477
- const $xeUpload = this
478
- const props = $xeUpload
479
-
480
- return Object.assign({}, props.imageConfig || props.imageStyle)
481
- },
482
- computeImgStyle () {
483
- const $xeUpload = this
484
-
485
- const imageOpts = $xeUpload.computeImageOpts
486
- const { width, height } = imageOpts
487
- const stys: Record<string, string> = {}
488
- if (width) {
489
- stys.width = toCssUnit(width)
490
- }
491
- if (height) {
492
- stys.height = toCssUnit(height)
493
- }
494
- return stys
495
- },
496
- computeMoreOpts () {
497
- const $xeUpload = this
498
- const props = $xeUpload
499
-
500
- return Object.assign({ showMoreButton: true }, props.moreConfig)
501
- }
502
- },
503
- watch: {
504
- value () {
505
- const $xeUpload = this
506
- $xeUpload.updateFileList()
507
- }
508
- },
509
- methods: {
510
- //
511
- // Method
512
- //
513
- dispatchEvent (type: ValueOf<VxeUploadEmits>, params: Record<string, any>, evnt: Event | null) {
514
- const $xeUpload = this
515
- $xeUpload.$emit(type, createEvent(evnt, { $upload: $xeUpload }, params))
516
- },
517
- emitModel (value: any) {
518
- const $xeUpload = this
519
-
520
- const { _events } = $xeUpload as any
521
- if (_events && _events.modelValue) {
522
- $xeUpload.$emit('modelValue', value)
523
- } else {
524
- $xeUpload.$emit('model-value', value)
525
- }
526
- },
527
- choose () {
528
- const $xeUpload = this
529
- return $xeUpload.handleChoose(null)
530
- },
531
- getPendingFiles () {
532
- const $xeUpload = this
533
- const reactData = $xeUpload.reactData
534
-
535
- const { fileList, fileCacheMaps } = reactData
536
- const pendingFiles: File[] = []
537
- fileList.forEach(item => {
538
- const fileKey = $xeUpload.getFieldKey(item)
539
- const cacheItem = fileCacheMaps[fileKey]
540
- if (cacheItem && cacheItem.status === 'pending') {
541
- pendingFiles.push(cacheItem.file)
542
- }
543
- })
544
- return pendingFiles
545
- },
546
- submit (isFull?: boolean) {
547
- const $xeUpload = this
548
- const props = $xeUpload
549
- const reactData = $xeUpload.reactData
550
-
551
- const { maxSimultaneousUploads } = props
552
- const msNum = XEUtils.toNumber(maxSimultaneousUploads || 1) || 1
553
- const { fileList, fileCacheMaps } = reactData
554
- const allPendingList = fileList.filter(item => {
555
- const fileKey = $xeUpload.getFieldKey(item)
556
- const cacheItem = fileCacheMaps[fileKey]
557
- return cacheItem && (cacheItem.status === 'pending' || (isFull && cacheItem.status === 'error'))
558
- })
559
-
560
- const handleSubmit = (item: VxeUploadDefines.FileObjItem): Promise<void> => {
561
- const fileKey = $xeUpload.getFieldKey(item)
562
- const cacheItem = fileCacheMaps[fileKey]
563
- if (cacheItem) {
564
- const file = cacheItem.file
565
- if (file && (cacheItem.status === 'pending' || (isFull && cacheItem.status === 'error'))) {
566
- cacheItem.loading = true
567
- cacheItem.percent = 0
568
- return $xeUpload.handleUploadResult(item, file).then(handleNextSubmit)
569
- }
570
- }
571
- return handleNextSubmit()
572
- }
573
-
574
- const handleNextSubmit = (): Promise<void> => {
575
- if (allPendingList.length) {
576
- const item = allPendingList[0]
577
- allPendingList.splice(0, 1)
578
- return handleSubmit(item).then(handleNextSubmit)
579
- }
580
- return Promise.resolve()
581
- }
582
-
583
- return Promise.all(allPendingList.splice(0, msNum).map(handleSubmit)).then(() => {
584
- // 完成
585
- })
586
- },
587
- getMoreVisible () {
588
- const $xeUpload = this
589
- const reactData = $xeUpload.reactData
590
-
591
- return reactData.showMorePopup
592
- },
593
- openMore () {
594
- const $xeUpload = this
595
-
596
- $xeUpload.handleMoreEvent({ $event: new Event('click') })
597
- return $xeUpload.$nextTick()
598
- },
599
- openMoreByEvent (evnt: Event) {
600
- const $xeUpload = this
601
-
602
- $xeUpload.handleMoreEvent({ $event: evnt })
603
- return $xeUpload.$nextTick()
604
- },
605
- closeMore () {
606
- const $xeUpload = this
607
- const internalData = $xeUpload.internalData
608
-
609
- if (VxeUI.modal) {
610
- VxeUI.modal.close(internalData.moreId)
611
- }
612
- return $xeUpload.$nextTick()
613
- },
614
- getFieldKey (item: VxeUploadDefines.FileObjItem) {
615
- const $xeUpload = this
616
-
617
- const keyField = $xeUpload.computeKeyField
618
- return item[keyField]
619
- },
620
- updateFileList () {
621
- const $xeUpload = this
622
- const props = $xeUpload
623
- const reactData = $xeUpload.reactData
624
-
625
- const { value, multiple } = props
626
- const formReadonly = $xeUpload.computeFormReadonly
627
- const keyField = $xeUpload.computeKeyField
628
- const nameProp = $xeUpload.computeNameProp
629
- const typeProp = $xeUpload.computeTypeProp
630
- const urlProp = $xeUpload.computeUrlProp
631
- const sizeProp = $xeUpload.computeSizeProp
632
- const fileList = value
633
- ? (value ? (XEUtils.isArray(value) ? value : [value]) : []).map(item => {
634
- if (!item || XEUtils.isString(item)) {
635
- const url = `${item || ''}`
636
- const urlObj = XEUtils.parseUrl(item)
637
- const name = (urlObj ? urlObj.searchQuery[nameProp] : '') || $xeUpload.parseFileName(url)
638
- return {
639
- [nameProp]: name,
640
- [typeProp]: (urlObj ? urlObj.searchQuery[typeProp] : '') || $xeUpload.parseFileType(name),
641
- [urlProp]: url,
642
- [sizeProp]: XEUtils.toNumber(urlObj ? urlObj.searchQuery[sizeProp] : 0) || 0,
643
- [keyField]: getUniqueKey()
644
- }
645
- }
646
- const name = item[nameProp] || ''
647
- item[nameProp] = name
648
- item[typeProp] = item[typeProp] || $xeUpload.parseFileType(name)
649
- item[urlProp] = item[urlProp] || ''
650
- item[sizeProp] = item[sizeProp] || 0
651
- item[keyField] = item[keyField] || getUniqueKey()
652
- return item
653
- })
654
- : []
655
- reactData.fileList = (formReadonly || multiple) ? fileList : (fileList.slice(0, 1))
656
- },
657
- parseFileName (url: string) {
658
- return decodeURIComponent(`${url || ''}`).split('/').pop() || ''
659
- },
660
- parseFileType (name: string) {
661
- const index = name.lastIndexOf('.')
662
- if (index > 0) {
663
- return name.substring(index + 1).toLowerCase()
664
- }
665
- return ''
666
- },
667
- handleChange (value: VxeUploadDefines.FileObjItem[]) {
668
- const $xeUpload = this
669
- const props = $xeUpload
670
-
671
- const { singleMode, urlMode, urlArgs } = props
672
- const urlProp = $xeUpload.computeUrlProp
673
- const nameProp = $xeUpload.computeNameProp
674
- let restList = value ? value.slice(0) : []
675
- if (urlMode) {
676
- restList = restList.map(item => {
677
- const url = item[urlProp]
678
- if (url && urlArgs) {
679
- const urlObj = XEUtils.parseUrl(url)
680
- if (!urlObj.searchQuery[nameProp]) {
681
- if (url.indexOf('blob:') === -1) {
682
- return `${url}${url.indexOf('?') === -1 ? '?' : '&'}${encodeURIComponent(item[nameProp] || '')}`
683
- }
684
- }
685
- }
686
- return url
687
- })
688
- }
689
- $xeUpload.emitModel(singleMode ? (restList[0] || null) : restList)
690
- },
691
- getThumbnailFileUrl (item: VxeUploadDefines.FileObjItem) {
692
- const $xeUpload = this
693
- const props = $xeUpload
694
-
695
- const getThumbnailUrlFn = props.getThumbnailUrlMethod || getConfig().upload.getThumbnailUrlMethod
696
- if (getThumbnailUrlFn) {
697
- return getThumbnailUrlFn({
698
- $upload: $xeUpload,
699
- option: item
700
- })
701
- }
702
- return $xeUpload.getFileUrl(item)
703
- },
704
- getFileUrl (item: VxeUploadDefines.FileObjItem) {
705
- const $xeUpload = this
706
- const props = $xeUpload
707
-
708
- const getUrlFn = props.getUrlMethod || getConfig().upload.getUrlMethod
709
- const urlProp = $xeUpload.computeUrlProp
710
- return getUrlFn
711
- ? getUrlFn({
712
- $upload: $xeUpload,
713
- option: item
714
- })
715
- : item[urlProp]
716
- },
717
- handleDefaultFilePreview (item: VxeUploadDefines.FileObjItem) {
718
- const $xeUpload = this
719
- const props = $xeUpload
720
- const internalData = $xeUpload.internalData
721
-
722
- const { imageTypes } = props
723
- const typeProp = $xeUpload.computeTypeProp
724
- const previewImageOpts = $xeUpload.computePreviewImageOpts
725
- const beforeDownloadFn = props.beforeDownloadMethod || getConfig().upload.beforeDownloadMethod
726
- const { imagePreviewTypes } = internalData
727
- // 如果是预览图片
728
- if (imagePreviewTypes.concat(imageTypes || []).some(type => `${type}`.toLowerCase() === `${item[typeProp]}`.toLowerCase())) {
729
- if (VxeUI.previewImage) {
730
- VxeUI.previewImage({
731
- ...previewImageOpts,
732
- urlList: [$xeUpload.getFileUrl(item)],
733
- beforeDownloadMethod: beforeDownloadFn
734
- ? () => {
735
- return beforeDownloadFn({
736
- $upload: $xeUpload,
737
- option: item
738
- })
739
- }
740
- : undefined
741
- })
742
- }
743
- }
744
- },
745
- handlePreviewFileEvent (evnt: MouseEvent, item: VxeUploadDefines.FileObjItem) {
746
- const $xeUpload = this
747
- const props = $xeUpload
748
-
749
- const previewFn = props.previewMethod || getConfig().upload.previewMethod
750
- if (props.showPreview) {
751
- if (previewFn) {
752
- previewFn({
753
- $upload: $xeUpload,
754
- option: item
755
- })
756
- } else {
757
- $xeUpload.handleDefaultFilePreview(item)
758
- }
759
- }
760
- },
761
- handlePreviewImageEvent (evnt: MouseEvent, item: VxeUploadDefines.FileObjItem, index: number) {
762
- const $xeUpload = this
763
- const props = $xeUpload
764
- const reactData = $xeUpload.reactData
765
-
766
- const { fileList } = reactData
767
- const previewImageOpts = $xeUpload.computePreviewImageOpts
768
- const previewFn = props.previewMethod || getConfig().upload.previewMethod
769
- const beforeDownloadFn = props.beforeDownloadMethod || getConfig().upload.beforeDownloadMethod
770
- if (props.showPreview) {
771
- if (previewFn) {
772
- previewFn({
773
- $upload: $xeUpload,
774
- option: item
775
- })
776
- } else if (VxeUI.previewImage) {
777
- VxeUI.previewImage({
778
- ...previewImageOpts,
779
- urlList: fileList.map(item => $xeUpload.getFileUrl(item)),
780
- activeIndex: index,
781
- beforeDownloadMethod: beforeDownloadFn
782
- ? ({ index }) => {
783
- return beforeDownloadFn({
784
- $upload: $xeUpload,
785
- option: fileList[index]
786
- })
787
- }
788
- : undefined
789
- })
790
- }
791
- }
792
- },
793
- handleUploadResult (item: VxeUploadDefines.FileObjItem, file: File) {
794
- const $xeUpload = this
795
- const props = $xeUpload
796
- const reactData = $xeUpload.reactData
797
-
798
- const { showErrorStatus } = props
799
- const fileKey = $xeUpload.getFieldKey(item)
800
- const uploadFn = props.uploadMethod || getConfig().upload.uploadMethod
801
- if (uploadFn) {
802
- return Promise.resolve(
803
- uploadFn({
804
- $upload: $xeUpload,
805
- file,
806
- option: item,
807
- updateProgress (percentNum) {
808
- const { fileCacheMaps } = reactData
809
- const cacheItem = fileCacheMaps[$xeUpload.getFieldKey(item)]
810
- if (cacheItem) {
811
- cacheItem.percent = Math.max(0, Math.min(99, XEUtils.toNumber(percentNum)))
812
- }
813
- }
814
- })
815
- ).then(res => {
816
- const { fileCacheMaps } = reactData
817
- const cacheItem = fileCacheMaps[fileKey]
818
- if (cacheItem) {
819
- cacheItem.percent = 100
820
- cacheItem.status = 'success'
821
- }
822
- // 处理动态字段双向绑定问题
823
- // Object.assign(item, res)
824
- XEUtils.each(res, (val, key) => {
825
- $xeUpload.$set(item, key, val)
826
- })
827
- $xeUpload.dispatchEvent('upload-success', { option: item, data: res }, null)
828
- }).catch((res) => {
829
- const { fileCacheMaps } = reactData
830
- const cacheItem = fileCacheMaps[fileKey]
831
- if (cacheItem) {
832
- cacheItem.status = 'error'
833
- }
834
- if (showErrorStatus) {
835
- // 处理动态字段双向绑定问题
836
- // Object.assign(item, res)
837
- XEUtils.each(res, (val, key) => {
838
- $xeUpload.$set(item, key, val)
839
- })
840
- } else {
841
- reactData.fileList = reactData.fileList.filter(obj => $xeUpload.getFieldKey(obj) !== fileKey)
842
- delete fileCacheMaps[fileKey]
843
- }
844
- $xeUpload.dispatchEvent('upload-error', { option: item, data: res }, null)
845
- }).finally(() => {
846
- const { fileCacheMaps } = reactData
847
- const cacheItem = fileCacheMaps[fileKey]
848
- if (cacheItem) {
849
- cacheItem.loading = false
850
- }
851
- })
852
- } else {
853
- const { fileCacheMaps } = reactData
854
- const cacheItem = fileCacheMaps[fileKey]
855
- if (cacheItem) {
856
- cacheItem.loading = false
857
- }
858
- }
859
- return Promise.resolve()
860
- },
861
- handleReUpload (item: VxeUploadDefines.FileObjItem) {
862
- const $xeUpload = this
863
- const props = $xeUpload
864
- const reactData = $xeUpload.reactData
865
-
866
- const { uploadMethod, urlMode } = props
867
- const { fileCacheMaps } = reactData
868
- const fileKey = $xeUpload.getFieldKey(item)
869
- const cacheItem = fileCacheMaps[fileKey]
870
- const uploadFn = uploadMethod || getConfig().upload.uploadMethod
871
- if (uploadFn && cacheItem) {
872
- const file = cacheItem.file
873
- cacheItem.loading = true
874
- cacheItem.status = 'pending'
875
- cacheItem.percent = 0
876
- $xeUpload.handleUploadResult(item, file).then(() => {
877
- if (urlMode) {
878
- $xeUpload.handleChange(reactData.fileList)
879
- }
880
- })
881
- }
882
- },
883
- handleUploadFile (files: File[], evnt: Event | null) {
884
- const $xeUpload = this
885
- const props = $xeUpload
886
- const reactData = $xeUpload.reactData
887
- const $xeForm = $xeUpload.$xeForm
888
- const formItemInfo = $xeUpload.formItemInfo
889
-
890
- const { multiple, urlMode, showLimitSize, limitSizeText, showLimitCount, limitCountText, autoSubmit } = props
891
- const { fileList } = reactData
892
- const beforeSelectFn = props.beforeSelectMethod || getConfig().upload.beforeSelectMethod
893
- const uploadFn = props.uploadMethod || getConfig().upload.uploadMethod
894
- const keyField = $xeUpload.computeKeyField
895
- const nameProp = $xeUpload.computeNameProp
896
- const typeProp = $xeUpload.computeTypeProp
897
- const urlProp = $xeUpload.computeUrlProp
898
- const sizeProp = $xeUpload.computeSizeProp
899
- const limitMaxSize = $xeUpload.computeLimitMaxSize
900
- const limitMaxCount = $xeUpload.computeLimitMaxCount
901
- const limitSizeUnit = $xeUpload.computeLimitSizeUnit
902
- let selectFiles = files
903
-
904
- if (multiple && limitMaxCount) {
905
- // 校验文件数量
906
- if (showLimitCount && fileList.length >= limitMaxCount) {
907
- if (VxeUI.modal) {
908
- VxeUI.modal.notification({
909
- title: getI18n('vxe.modal.errTitle'),
910
- status: 'error',
911
- content: limitCountText ? `${XEUtils.isFunction(limitCountText) ? limitCountText({ maxCount: limitMaxCount }) : limitCountText}` : getI18n('vxe.upload.overCountErr', [limitMaxCount])
912
- })
913
- }
914
- return
915
- }
916
- const overNum = selectFiles.length - (limitMaxCount - fileList.length)
917
- if (showLimitCount && overNum > 0) {
918
- const overExtraList = selectFiles.slice(limitMaxCount - fileList.length)
919
- if (limitCountText) {
920
- VxeUI.modal.notification({
921
- title: getI18n('vxe.modal.errTitle'),
922
- status: 'error',
923
- content: `${XEUtils.isFunction(limitCountText) ? limitCountText({ maxCount: limitMaxCount }) : limitCountText}`
924
- })
925
- } else if (VxeUI.modal) {
926
- VxeUI.modal.notification({
927
- title: getI18n('vxe.modal.errTitle'),
928
- status: 'error',
929
- slots: {
930
- default (params, h) {
931
- return h('div', {
932
- class: 'vxe-upload--file-message-over-error'
933
- }, [
934
- h('div', {}, getI18n('vxe.upload.overCountExtraErr', [limitMaxCount, overNum])),
935
- h('div', {
936
- class: 'vxe-upload--file-message-over-extra'
937
- }, overExtraList.map((file, index) => {
938
- return h('div', {
939
- key: index,
940
- class: 'vxe-upload--file-message-over-extra-item'
941
- }, file.name)
942
- }))
943
- ])
944
- }
945
- }
946
- })
947
- }
948
- }
949
- selectFiles = selectFiles.slice(0, limitMaxCount - fileList.length)
950
- }
951
-
952
- // 校验文件大小
953
- if (showLimitSize && limitMaxSize) {
954
- for (let i = 0; i < files.length; i++) {
955
- const file = files[0]
956
- if (file.size > limitMaxSize) {
957
- if (VxeUI.modal) {
958
- VxeUI.modal.notification({
959
- title: getI18n('vxe.modal.errTitle'),
960
- status: 'error',
961
- content: limitSizeText ? `${XEUtils.isFunction(limitSizeText) ? limitSizeText({ maxSize: limitMaxSize }) : limitSizeText}` : getI18n('vxe.upload.overSizeErr', [limitSizeUnit])
962
- })
963
- }
964
- return
965
- }
966
- }
967
- }
968
-
969
- const cacheMaps = Object.assign({}, reactData.fileCacheMaps)
970
- const newFileList = multiple ? fileList : []
971
- const uploadPromiseRests: any[] = []
972
- selectFiles.forEach(file => {
973
- const { name } = file
974
- const fileKey = getUniqueKey()
975
- const fileObj: VxeUploadDefines.FileObjItem = {
976
- [nameProp]: name,
977
- [typeProp]: $xeUpload.parseFileType(name),
978
- [sizeProp]: file.size,
979
- [urlProp]: URL.createObjectURL(file),
980
- [keyField]: fileKey
981
- }
982
- if (uploadFn) {
983
- cacheMaps[fileKey] = {
984
- file: file,
985
- loading: !!autoSubmit,
986
- status: 'pending',
987
- percent: 0
988
- }
989
- }
990
- const item = fileObj
991
- if (!beforeSelectFn || beforeSelectFn({ $upload: $xeUpload, file })) {
992
- if (uploadFn && autoSubmit) {
993
- uploadPromiseRests.push(
994
- $xeUpload.handleUploadResult(item, file)
995
- )
996
- }
997
- newFileList.push(item)
998
- }
999
- })
1000
- reactData.fileList = newFileList
1001
- reactData.fileCacheMaps = cacheMaps
1002
- newFileList.forEach(item => {
1003
- $xeUpload.dispatchEvent('add', { option: item }, evnt)
1004
- })
1005
- Promise.all(urlMode ? uploadPromiseRests : []).then(() => {
1006
- const restFileList = reactData.fileList
1007
- $xeUpload.handleChange(restFileList)
1008
- // 自动更新校验状态
1009
- if ($xeForm && formItemInfo) {
1010
- $xeForm.triggerItemEvent(evnt as any, formItemInfo.itemConfig.field, restFileList)
1011
- }
1012
- })
1013
- },
1014
- handleChoose (evnt: MouseEvent | null) {
1015
- const $xeUpload = this
1016
- const props = $xeUpload
1017
-
1018
- const { multiple, imageTypes, fileTypes } = props
1019
- const isDisabled = $xeUpload.computeIsDisabled
1020
- const isImage = $xeUpload.computeIsImage
1021
- if (isDisabled) {
1022
- return Promise.resolve({
1023
- status: false,
1024
- files: [],
1025
- file: null
1026
- })
1027
- }
1028
- return readLocalFile({
1029
- multiple,
1030
- types: isImage ? imageTypes : fileTypes
1031
- }).then((params) => {
1032
- $xeUpload.handleUploadFile(params.files, evnt)
1033
- return params
1034
- })
1035
- },
1036
- clickEvent (evnt: MouseEvent) {
1037
- const $xeUpload = this
1038
-
1039
- $xeUpload.handleChoose(evnt).catch(() => {
1040
- // 错误文件类型
1041
- })
1042
- },
1043
- handleRemoveEvent (evnt: MouseEvent, item: VxeUploadDefines.FileObjItem, index: number) {
1044
- const $xeUpload = this
1045
- const reactData = $xeUpload.reactData
1046
- const $xeForm = $xeUpload.$xeForm
1047
- const formItemInfo = $xeUpload.formItemInfo
1048
-
1049
- const { fileList } = reactData
1050
- fileList.splice(index, 1)
1051
- $xeUpload.handleChange(fileList)
1052
- // 自动更新校验状态
1053
- if ($xeForm && formItemInfo) {
1054
- $xeForm.triggerItemEvent(evnt, formItemInfo.itemConfig.field, fileList)
1055
- }
1056
- $xeUpload.dispatchEvent('remove', { option: item }, evnt)
1057
- },
1058
- removeFileEvent (evnt: MouseEvent, item: VxeUploadDefines.FileObjItem, index: number) {
1059
- const $xeUpload = this
1060
- const props = $xeUpload
1061
-
1062
- const beforeRemoveFn = props.beforeRemoveMethod || getConfig().upload.beforeRemoveMethod
1063
- const removeFn = props.removeMethod || getConfig().upload.removeMethod
1064
- Promise.resolve(
1065
- beforeRemoveFn
1066
- ? beforeRemoveFn({
1067
- $upload: $xeUpload,
1068
- option: item
1069
- })
1070
- : true
1071
- ).then(status => {
1072
- if (status) {
1073
- if (removeFn) {
1074
- Promise.resolve(
1075
- removeFn({
1076
- $upload: $xeUpload,
1077
- option: item
1078
- })
1079
- ).then(() => {
1080
- $xeUpload.handleRemoveEvent(evnt, item, index)
1081
- }).catch(e => e)
1082
- } else {
1083
- $xeUpload.handleRemoveEvent(evnt, item, index)
1084
- }
1085
- } else {
1086
- $xeUpload.dispatchEvent('remove-fail', { option: item }, evnt)
1087
- }
1088
- })
1089
- },
1090
- handleDownloadEvent (evnt: MouseEvent, item: VxeUploadDefines.FileObjItem) {
1091
- const $xeUpload = this
1092
-
1093
- $xeUpload.dispatchEvent('download', { option: item }, evnt)
1094
- },
1095
- downloadFileEvent (evnt: MouseEvent, item: VxeUploadDefines.FileObjItem) {
1096
- const $xeUpload = this
1097
- const props = $xeUpload
1098
-
1099
- const beforeDownloadFn = props.beforeDownloadMethod || getConfig().upload.beforeDownloadMethod
1100
- const downloadFn = props.downloadMethod || getConfig().upload.downloadMethod
1101
- Promise.resolve(
1102
- beforeDownloadFn
1103
- ? beforeDownloadFn({
1104
- $upload: $xeUpload,
1105
- option: item
1106
- })
1107
- : true
1108
- ).then(status => {
1109
- if (status) {
1110
- if (downloadFn) {
1111
- Promise.resolve(
1112
- downloadFn({
1113
- $upload: $xeUpload,
1114
- option: item
1115
- })
1116
- ).then(() => {
1117
- $xeUpload.handleDownloadEvent(evnt, item)
1118
- }).catch(e => e)
1119
- } else {
1120
- $xeUpload.handleDownloadEvent(evnt, item)
1121
- }
1122
- } else {
1123
- $xeUpload.dispatchEvent('download-fail', { option: item }, evnt)
1124
- }
1125
- })
1126
- },
1127
- handleUploadDragleaveEvent (evnt: DragEvent) {
1128
- const $xeUpload = this
1129
- const reactData = $xeUpload.reactData
1130
-
1131
- const targetElem = evnt.currentTarget as HTMLDivElement
1132
- const { clientX, clientY } = evnt
1133
- if (targetElem) {
1134
- const { x: targetX, y: targetY, height: targetHeight, width: targetWidth } = targetElem.getBoundingClientRect()
1135
- if (clientX < targetX || clientX > targetX + targetWidth || clientY < targetY || clientY > targetY + targetHeight) {
1136
- reactData.isDragUploadStatus = false
1137
- }
1138
- }
1139
- },
1140
- handleUploadDragoverEvent (evnt: DragEvent) {
1141
- const $xeUpload = this
1142
- const reactData = $xeUpload.reactData
1143
-
1144
- const dataTransfer = evnt.dataTransfer
1145
- if (dataTransfer) {
1146
- const { items } = dataTransfer
1147
- if (items && items.length) {
1148
- evnt.preventDefault()
1149
- reactData.isDragUploadStatus = true
1150
- }
1151
- }
1152
- },
1153
- uploadTransferFileEvent (evnt: Event, files: File[]) {
1154
- const $xeUpload = this
1155
- const props = $xeUpload
1156
- const internalData = $xeUpload.internalData
1157
-
1158
- const { imageTypes, fileTypes } = props
1159
- const { imagePreviewTypes } = internalData
1160
- const isImage = $xeUpload.computeIsImage
1161
- if (isImage) {
1162
- const pasteImgTypes = imagePreviewTypes.concat(imageTypes && imageTypes.length ? imageTypes : [])
1163
- files = files.filter(file => {
1164
- const fileType = `${file.type.split('/')[1] || ''}`.toLowerCase()
1165
- if (pasteImgTypes.some(type => `${type}`.toLowerCase() === fileType)) {
1166
- return true
1167
- }
1168
- return false
1169
- })
1170
- } else {
1171
- if (fileTypes && fileTypes.length) {
1172
- const errTypes: string[] = []
1173
- files.forEach(file => {
1174
- const fileType = $xeUpload.parseFileType(file.name)
1175
- if (!fileTypes.some(type => `${type}`.toLowerCase() === fileType)) {
1176
- errTypes.push(fileType)
1177
- }
1178
- })
1179
- if (errTypes.length) {
1180
- if (VxeUI.modal) {
1181
- VxeUI.modal.message({
1182
- content: getI18n('vxe.error.notType', [errTypes.join(', ')]),
1183
- status: 'error'
1184
- })
1185
- }
1186
- return
1187
- }
1188
- }
1189
- }
1190
- // 如果全部不满足条件
1191
- if (!files.length) {
1192
- if (VxeUI.modal) {
1193
- VxeUI.modal.notification({
1194
- title: getI18n('vxe.modal.errTitle'),
1195
- status: 'error',
1196
- content: getI18n('vxe.upload.uploadTypeErr')
1197
- })
1198
- }
1199
- return
1200
- }
1201
- $xeUpload.handleUploadFile(files, evnt)
1202
- },
1203
- handleUploadDropEvent (evnt: DragEvent) {
1204
- const $xeUpload = this
1205
- const reactData = $xeUpload.reactData
1206
-
1207
- const dataTransfer = evnt.dataTransfer
1208
- if (dataTransfer) {
1209
- const { items } = dataTransfer
1210
- if (items && items.length) {
1211
- evnt.preventDefault()
1212
- const files = handleTransferFiles(items)
1213
- if (files.length) {
1214
- $xeUpload.uploadTransferFileEvent(evnt, files)
1215
- }
1216
- }
1217
- }
1218
- reactData.isDragUploadStatus = false
1219
- },
1220
- handleMoreEvent (evntParams: VxeComponentEventParams) {
1221
- const $xeUpload = this
1222
- const props = $xeUpload
1223
- const slots = $xeUpload.$scopedSlots
1224
- const reactData = $xeUpload.reactData
1225
- const internalData = $xeUpload.internalData
1226
-
1227
- const { xID } = $xeUpload
1228
-
1229
- const formReadonly = $xeUpload.computeFormReadonly
1230
- const isImage = $xeUpload.computeIsImage
1231
-
1232
- const evnt = evntParams.$event
1233
- if (VxeUI.modal) {
1234
- VxeUI.modal.open({
1235
- id: internalData.moreId,
1236
- title: formReadonly ? getI18n('vxe.upload.morePopup.readTitle') : getI18n(`vxe.upload.morePopup.${isImage ? 'imageTitle' : 'fileTitle'}`),
1237
- width: 660,
1238
- height: 500,
1239
- escClosable: true,
1240
- showMaximize: true,
1241
- resize: true,
1242
- maskClosable: true,
1243
- slots: {
1244
- default (params, h) {
1245
- const { showErrorStatus, dragToUpload, dragSort, dragPlaceholder } = props
1246
- const { isActivated, isDragMove, isDragUploadStatus, dragIndex } = reactData
1247
- const { fileList } = reactData
1248
- const isDisabled = $xeUpload.computeIsDisabled
1249
- const moreContSlot = slots.moreContent || slots['more-content']
1250
-
1251
- const ons: Record<string, any> = {}
1252
- if (dragToUpload && dragIndex === -1) {
1253
- ons.dragover = $xeUpload.handleUploadDragoverEvent
1254
- ons.dragleave = $xeUpload.handleUploadDragleaveEvent
1255
- ons.drop = $xeUpload.handleUploadDropEvent
1256
- }
1257
-
1258
- return h('div', {
1259
- attrs: {
1260
- id: `refPopupElem${xID}`
1261
- },
1262
- class: ['vxe-upload--more-popup', {
1263
- 'is--readonly': formReadonly,
1264
- 'is--disabled': isDisabled,
1265
- 'is--active': isActivated,
1266
- 'show--error': showErrorStatus,
1267
- 'is--drag': isDragUploadStatus
1268
- }],
1269
- on: ons
1270
- }, moreContSlot
1271
- ? getSlotVNs(moreContSlot({ options: fileList }))
1272
- : [
1273
- isImage
1274
- ? (
1275
- dragSort
1276
- ? h('transition-group', {
1277
- props: {
1278
- name: `vxe-upload--drag-list${isDragMove ? '' : '-disabled'}`,
1279
- tag: 'div'
1280
- },
1281
- class: 'vxe-upload--image-more-list'
1282
- }, $xeUpload.renderImageItemList(h, fileList, true).concat($xeUpload.renderImageAction(h, true)))
1283
- : h('div', {
1284
- class: 'vxe-upload--image-more-list'
1285
- }, $xeUpload.renderImageItemList(h, fileList, true).concat($xeUpload.renderImageAction(h, true)))
1286
- )
1287
- : h('div', {
1288
- class: 'vxe-upload--file-more-list'
1289
- }, [
1290
- $xeUpload.renderFileAction(h, true),
1291
- (
1292
- dragSort
1293
- ? h('transition-group', {
1294
- props: {
1295
- name: `vxe-upload--drag-list${isDragMove ? '' : '-disabled'}`,
1296
- tag: 'div'
1297
- },
1298
- class: 'vxe-upload--file-list'
1299
- }, $xeUpload.renderFileItemList(h, fileList, true))
1300
- : h('div', {
1301
- class: 'vxe-upload--file-list'
1302
- }, $xeUpload.renderFileItemList(h, fileList, true))
1303
- )
1304
- ]),
1305
- dragSort
1306
- ? h('div', {
1307
- attrs: {
1308
- id: `refModalDragLineElem${xID}`
1309
- },
1310
- class: 'vxe-upload--drag-line'
1311
- })
1312
- : renderEmptyElement($xeUpload),
1313
- isDragUploadStatus
1314
- ? h('div', {
1315
- class: 'vxe-upload--drag-placeholder'
1316
- }, dragPlaceholder || getI18n('vxe.upload.dragPlaceholder'))
1317
- : renderEmptyElement($xeUpload)
1318
- ])
1319
- }
1320
- },
1321
- events: {
1322
- show () {
1323
- reactData.showMorePopup = true
1324
- },
1325
- hide ({ $event }) {
1326
- reactData.showMorePopup = false
1327
- if ($event) {
1328
- $xeUpload.dispatchEvent('more-visible', { visible: false }, $event)
1329
- }
1330
- }
1331
- }
1332
- })
1333
- if (evnt) {
1334
- $xeUpload.dispatchEvent('more-visible', { visible: true }, evnt)
1335
- }
1336
- }
1337
- },
1338
- // 拖拽
1339
- handleDragSortDragstartEvent (evnt: DragEvent) {
1340
- const $xeUpload = this
1341
- const reactData = $xeUpload.reactData
1342
-
1343
- evnt.stopPropagation()
1344
- if (evnt.dataTransfer) {
1345
- evnt.dataTransfer.setDragImage(getTpImg(), 0, 0)
1346
- }
1347
- const dragEl = evnt.currentTarget as HTMLElement
1348
- const parentEl = dragEl.parentElement as HTMLDivElement
1349
- const dragIndex = XEUtils.findIndexOf(Array.from(parentEl.children), item => dragEl === item)
1350
- reactData.isDragMove = true
1351
- reactData.dragIndex = dragIndex
1352
- setTimeout(() => {
1353
- reactData.isDragMove = false
1354
- }, 500)
1355
- },
1356
- handleDragSortDragoverEvent (evnt: DragEvent) {
1357
- const $xeUpload = this
1358
- const reactData = $xeUpload.reactData
1359
- const internalData = $xeUpload.internalData
1360
-
1361
- evnt.stopPropagation()
1362
- evnt.preventDefault()
1363
- const { dragIndex } = reactData
1364
- if (dragIndex === -1) {
1365
- return
1366
- }
1367
- const isImage = $xeUpload.computeIsImage
1368
- const dragEl = evnt.currentTarget as HTMLElement
1369
- const parentEl = dragEl.parentElement as HTMLDivElement
1370
- const currIndex = XEUtils.findIndexOf(Array.from(parentEl.children), item => dragEl === item)
1371
- let dragPos: 'top' | 'bottom' | 'left' | 'right' | '' = ''
1372
- if (isImage) {
1373
- const offsetX = evnt.clientX - dragEl.getBoundingClientRect().x
1374
- dragPos = offsetX < dragEl.clientWidth / 2 ? 'left' : 'right'
1375
- } else {
1376
- const offsetY = evnt.clientY - dragEl.getBoundingClientRect().y
1377
- dragPos = offsetY < dragEl.clientHeight / 2 ? 'top' : 'bottom'
1378
- }
1379
- if (dragIndex === currIndex) {
1380
- showDropTip($xeUpload, evnt, dragEl, dragPos)
1381
- return
1382
- }
1383
- showDropTip($xeUpload, evnt, dragEl, dragPos)
1384
- internalData.prevDragIndex = currIndex
1385
- internalData.prevDragPos = dragPos
1386
- },
1387
- handleDragSortDragendEvent (evnt: DragEvent) {
1388
- const $xeUpload = this
1389
- const reactData = $xeUpload.reactData
1390
- const internalData = $xeUpload.internalData
1391
-
1392
- const { fileList, dragIndex } = reactData
1393
- const { prevDragIndex, prevDragPos } = internalData
1394
- const oldIndex = dragIndex
1395
- const targetIndex = prevDragIndex
1396
- const dragOffsetIndex = prevDragPos === 'bottom' || prevDragPos === 'right' ? 1 : 0
1397
- const oldItem = fileList[oldIndex]
1398
- const newItem = fileList[targetIndex]
1399
- if (oldItem && newItem) {
1400
- fileList.splice(oldIndex, 1)
1401
- const ptfIndex = XEUtils.findIndexOf(fileList, item => newItem === item)
1402
- const nIndex = ptfIndex + dragOffsetIndex
1403
- fileList.splice(nIndex, 0, oldItem)
1404
- $xeUpload.dispatchEvent('sort-dragend', {
1405
- oldItem: oldItem,
1406
- newItem: newItem,
1407
- dragPos: prevDragPos as any,
1408
- offsetIndex: dragOffsetIndex,
1409
- _index: {
1410
- newIndex: nIndex,
1411
- oldIndex: oldIndex
1412
- }
1413
- }, evnt)
1414
- }
1415
- hideDropTip($xeUpload)
1416
- reactData.dragIndex = -1
1417
- },
1418
- handleItemMousedownEvent (evnt: MouseEvent) {
1419
- const $xeUpload = this
1420
- const $xeTable = $xeUpload.$xeTable
1421
- const reactData = $xeUpload.reactData
1422
-
1423
- if ($xeTable) {
1424
- evnt.stopPropagation()
1425
- }
1426
- reactData.isActivated = true
1427
- },
1428
- handleGlobalPasteEvent (evnt: ClipboardEvent) {
1429
- const $xeUpload = this
1430
- const props = $xeUpload
1431
- const reactData = $xeUpload.reactData
1432
-
1433
- const { pasteToUpload } = props
1434
- const { isActivated } = reactData
1435
- if (!isActivated || !pasteToUpload) {
1436
- return
1437
- }
1438
- const clipboardData: DataTransfer = evnt.clipboardData || (evnt as any).originalEvent.clipboardData
1439
- if (!clipboardData) {
1440
- return
1441
- }
1442
- const { items } = clipboardData
1443
- if (!items) {
1444
- return
1445
- }
1446
- const files = handleTransferFiles(items)
1447
- if (files.length) {
1448
- evnt.preventDefault()
1449
- $xeUpload.uploadTransferFileEvent(evnt, files)
1450
- }
1451
- },
1452
- handleGlobalClickEvent (evnt: MouseEvent) {
1453
- const $xeUpload = this
1454
- const reactData = $xeUpload.reactData
1455
-
1456
- const el = $xeUpload.$refs.refElem as HTMLDivElement
1457
- const popupEl = $xeUpload.$refs.refPopupElem as HTMLDivElement
1458
- let isActivated = getEventTargetNode(evnt, el).flag
1459
- if (!isActivated && popupEl) {
1460
- const parentEl = popupEl.parentElement || popupEl
1461
- const modalEl = parentEl ? parentEl.parentElement : parentEl
1462
- isActivated = getEventTargetNode(evnt, modalEl).flag
1463
- }
1464
- reactData.isActivated = isActivated
1465
- },
1466
- handleGlobalBlurEvent () {
1467
- const $xeUpload = this
1468
- const reactData = $xeUpload.reactData
1469
-
1470
- reactData.isActivated = false
1471
- },
1472
-
1473
- //
1474
- // Render
1475
- //
1476
- renderFileItemList (h: CreateElement, currList: VxeUploadDefines.FileObjItem[], isMoreView: boolean) {
1477
- const $xeUpload = this
1478
- const props = $xeUpload
1479
- const slots = $xeUpload.$scopedSlots
1480
- const reactData = $xeUpload.reactData
1481
-
1482
- const { showRemoveButton, showDownloadButton, showProgress, progressText, showPreview, showErrorStatus, dragSort, autoSubmit, showSubmitButton } = props
1483
- const { fileList, fileCacheMaps } = reactData
1484
- const isDisabled = $xeUpload.computeIsDisabled
1485
- const formReadonly = $xeUpload.computeFormReadonly
1486
- const nameProp = $xeUpload.computeNameProp
1487
- const typeProp = $xeUpload.computeTypeProp
1488
- const optionSlot = slots.option
1489
- const actionSlot = slots.action
1490
- const cornerSlot = slots.corner
1491
- const nameSlot = slots.name
1492
-
1493
- const ons: Record<string, any> = {}
1494
- if (dragSort && currList.length > 1) {
1495
- ons.dragstart = $xeUpload.handleDragSortDragstartEvent
1496
- ons.dragover = $xeUpload.handleDragSortDragoverEvent
1497
- ons.dragend = $xeUpload.handleDragSortDragendEvent
1498
- }
1499
-
1500
- return currList.map((item, index) => {
1501
- const fileKey = $xeUpload.getFieldKey(item)
1502
- const cacheItem = fileCacheMaps[fileKey]
1503
- let isLoading = false
1504
- let isError = false
1505
- let isPending = false
1506
- const fileName = `${item[nameProp] || ''}`
1507
- if (cacheItem) {
1508
- isLoading = cacheItem.loading
1509
- isError = cacheItem.status === 'error'
1510
- isPending = cacheItem.status === 'pending'
1511
- }
1512
- return h('div', {
1513
- key: dragSort ? fileKey : index,
1514
- class: ['vxe-upload--file-item', {
1515
- 'is--preview': showPreview,
1516
- 'is--loading': isLoading,
1517
- 'is--pending': isPending,
1518
- 'is--error': isError
1519
- }],
1520
- attrs: {
1521
- fileid: fileKey,
1522
- draggable: dragSort ? true : null
1523
- },
1524
- on: ons
1525
- }, optionSlot
1526
- ? getSlotVNs(optionSlot({ option: item, isMoreView, options: fileList }))
1527
- : [
1528
- h('div', {
1529
- class: 'vxe-upload--file-item-icon'
1530
- }, [
1531
- h('i', {
1532
- class: getIcon()[`UPLOAD_FILE_TYPE_${`${item[typeProp]}`.toLocaleUpperCase() as 'DEFAULT'}`] || getIcon().UPLOAD_FILE_TYPE_DEFAULT
1533
- })
1534
- ]),
1535
- h('div', {
1536
- class: 'vxe-upload--file-item-name',
1537
- attrs: {
1538
- title: fileName
1539
- },
1540
- on: {
1541
- click (evnt: MouseEvent) {
1542
- if (!isLoading && !isError) {
1543
- $xeUpload.handlePreviewFileEvent(evnt, item)
1544
- }
1545
- }
1546
- }
1547
- }, nameSlot ? getSlotVNs(nameSlot({ option: item, isMoreView, options: fileList })) : fileName),
1548
- isLoading
1549
- ? h('div', {
1550
- class: 'vxe-upload--file-item-loading-icon'
1551
- }, [
1552
- h('i', {
1553
- class: getIcon().UPLOAD_LOADING
1554
- })
1555
- ])
1556
- : renderEmptyElement($xeUpload),
1557
- showProgress && isLoading && cacheItem
1558
- ? h('div', {
1559
- class: 'vxe-upload--file-item-loading-text'
1560
- }, progressText ? XEUtils.toFormatString(`${XEUtils.isFunction(progressText) ? progressText({}) : progressText}`, { percent: cacheItem.percent }) : getI18n('vxe.upload.uploadProgress', [cacheItem.percent]))
1561
- : renderEmptyElement($xeUpload),
1562
- !isLoading && ((isError && showErrorStatus) || (isPending && showSubmitButton && !autoSubmit))
1563
- ? h('div', {
1564
- class: 'vxe-upload--file-item-rebtn'
1565
- }, [
1566
- h(VxeButtonComponent, {
1567
- props: {
1568
- icon: isError ? getIcon().UPLOAD_IMAGE_RE_UPLOAD : getIcon().UPLOAD_IMAGE_UPLOAD,
1569
- mode: 'text',
1570
- status: 'primary',
1571
- content: isError ? getI18n('vxe.upload.reUpload') : getI18n('vxe.upload.manualUpload')
1572
- },
1573
- on: {
1574
- click () {
1575
- $xeUpload.handleReUpload(item)
1576
- }
1577
- }
1578
- })
1579
- ])
1580
- : renderEmptyElement($xeUpload),
1581
- h('div', {
1582
- class: 'vxe-upload--file-item-btn-wrapper'
1583
- }, actionSlot
1584
- ? getSlotVNs(actionSlot({ option: item, isMoreView, options: fileList, readonly: formReadonly }))
1585
- : [
1586
- cornerSlot
1587
- ? h('div', {
1588
- class: 'vxe-upload--file-item-action'
1589
- }, getSlotVNs(cornerSlot({ option: item, isMoreView, options: fileList, readonly: formReadonly })))
1590
- : renderEmptyElement($xeUpload),
1591
- showDownloadButton && !isLoading
1592
- ? h('div', {
1593
- class: 'vxe-upload--file-item-download-btn',
1594
- on: {
1595
- click (evnt: MouseEvent) {
1596
- $xeUpload.downloadFileEvent(evnt, item)
1597
- }
1598
- }
1599
- }, [
1600
- h('i', {
1601
- class: getIcon().UPLOAD_FILE_DOWNLOAD
1602
- })
1603
- ])
1604
- : renderEmptyElement($xeUpload),
1605
- showRemoveButton && !formReadonly && !isDisabled && !isLoading
1606
- ? h('div', {
1607
- class: 'vxe-upload--file-item-remove-btn',
1608
- on: {
1609
- click (evnt: MouseEvent) {
1610
- $xeUpload.removeFileEvent(evnt, item, index)
1611
- }
1612
- }
1613
- }, [
1614
- h('i', {
1615
- class: getIcon().UPLOAD_FILE_REMOVE
1616
- })
1617
- ])
1618
- : renderEmptyElement($xeUpload)
1619
- ])
1620
- ])
1621
- })
1622
- },
1623
- renderFileAction (h: CreateElement, isMoreView: boolean) {
1624
- const $xeUpload = this
1625
- const props = $xeUpload
1626
- const slots = $xeUpload.$scopedSlots
1627
- const reactData = $xeUpload.reactData
1628
-
1629
- const { showUploadButton, buttonText, buttonIcon, showButtonText, showButtonIcon, autoHiddenButton } = props
1630
- const { fileList } = reactData
1631
- const isDisabled = $xeUpload.computeIsDisabled
1632
- const formReadonly = $xeUpload.computeFormReadonly
1633
- const showTipText = $xeUpload.computedShowTipText
1634
- const defTipText = $xeUpload.computedDefTipText
1635
- const overCount = $xeUpload.computeOverCount
1636
- const defaultSlot = slots.default
1637
- const tipSlot = slots.tip || slots.hint
1638
-
1639
- if (formReadonly || !showUploadButton) {
1640
- return renderEmptyElement($xeUpload)
1641
- }
1642
- return h('div', {
1643
- class: 'vxe-upload--file-action'
1644
- }, [
1645
- autoHiddenButton && overCount
1646
- ? renderEmptyElement($xeUpload)
1647
- : h('div', {
1648
- class: 'vxe-upload--file-action-btn',
1649
- on: {
1650
- click: $xeUpload.clickEvent
1651
- }
1652
- }, defaultSlot
1653
- ? getSlotVNs(defaultSlot({ isMoreView, options: fileList, $upload: $xeUpload }))
1654
- : [
1655
- h(VxeButtonComponent, {
1656
- class: 'vxe-upload--file-action-button',
1657
- props: {
1658
- content: (isMoreView || showButtonText) ? (buttonText ? `${XEUtils.isFunction(buttonText) ? buttonText({}) : buttonText}` : getI18n('vxe.upload.fileBtnText')) : '',
1659
- icon: showButtonIcon ? (buttonIcon || getIcon().UPLOAD_FILE_ADD) : '',
1660
- disabled: isDisabled
1661
- }
1662
- })
1663
- ]),
1664
- showTipText && (defTipText || tipSlot)
1665
- ? h('div', {
1666
- class: 'vxe-upload--file-action-tip'
1667
- }, tipSlot ? getSlotVNs(tipSlot({ isMoreView, options: fileList, $upload: $xeUpload })) : `${defTipText}`)
1668
- : renderEmptyElement($xeUpload)
1669
- ])
1670
- },
1671
- rendeFileMode (h: CreateElement) {
1672
- const $xeUpload = this
1673
- const props = $xeUpload
1674
- const slots = $xeUpload.$scopedSlots
1675
- const reactData = $xeUpload.reactData
1676
-
1677
- const { showList, moreConfig, dragSort } = props
1678
- const { fileList, isDragMove } = reactData
1679
- const moreOpts = $xeUpload.computeMoreOpts
1680
- const { maxCount, showMoreButton, layout, moreButtonText } = moreOpts
1681
- const isHorizontal = layout === 'horizontal'
1682
- const moreBtnSlot = slots.moreButton || slots['more-button']
1683
-
1684
- let currList = fileList
1685
- let overMaxNum = 0
1686
- let isMoreMax = false
1687
- let isMiniMore = false
1688
- if (XEUtils.isNumber(maxCount) && fileList.length > maxCount) {
1689
- isMoreMax = true
1690
- isMiniMore = maxCount === 0
1691
- overMaxNum = fileList.length - maxCount
1692
- currList = fileList.slice(0, maxCount)
1693
- }
1694
-
1695
- return h('div', {
1696
- key: 'all',
1697
- class: 'vxe-upload--file-wrapper'
1698
- }, showList
1699
- ? [
1700
- showMoreButton && moreConfig && isHorizontal
1701
- ? renderEmptyElement($xeUpload)
1702
- : $xeUpload.renderFileAction(h, true),
1703
- h('div', {
1704
- class: ['vxe-upload--file-list-wrapper', {
1705
- 'is--horizontal': isHorizontal
1706
- }]
1707
- }, [
1708
- currList.length
1709
- ? (
1710
- dragSort
1711
- ? h('transition-group', {
1712
- attrs: {
1713
- name: `vxe-upload--drag-list${isDragMove ? '' : '-disabled'}`,
1714
- tag: 'div'
1715
- },
1716
- class: 'vxe-upload--file-list'
1717
- }, $xeUpload.renderFileItemList(h, currList, false))
1718
- : h('div', {
1719
- class: 'vxe-upload--file-list'
1720
- }, $xeUpload.renderFileItemList(h, currList, false))
1721
- )
1722
- : renderEmptyElement($xeUpload),
1723
- showMoreButton && overMaxNum
1724
- ? h('div', {
1725
- class: 'vxe-upload--file-over-more'
1726
- }, moreBtnSlot
1727
- ? getSlotVNs(moreBtnSlot({ options: fileList }))
1728
- : [
1729
- h(VxeButtonComponent, {
1730
- props: {
1731
- mode: 'text',
1732
- content: moreButtonText ? (XEUtils.isFunction(moreButtonText) ? moreButtonText({ $upload: $xeUpload, options: fileList }) : XEUtils.toFormatString(moreButtonText, [fileList.length])) : getI18n(isMoreMax && isMiniMore ? 'vxe.upload.moreFileBtnText' : 'vxe.upload.moreBtnText', [fileList.length]),
1733
- status: 'primary'
1734
- },
1735
- on: {
1736
- click: $xeUpload.handleMoreEvent
1737
- }
1738
- })
1739
- ])
1740
- : renderEmptyElement($xeUpload),
1741
- showMoreButton && moreConfig && isHorizontal
1742
- ? $xeUpload.renderFileAction(h, false)
1743
- : renderEmptyElement($xeUpload)
1744
- ])
1745
- ]
1746
- : [
1747
- $xeUpload.renderFileAction(h, false)
1748
- ])
1749
- },
1750
- renderImageItemList (h: CreateElement, currList: VxeUploadDefines.FileObjItem[], isMoreView: boolean) {
1751
- const $xeUpload = this
1752
- const props = $xeUpload
1753
- const slots = $xeUpload.$scopedSlots
1754
- const reactData = $xeUpload.reactData
1755
-
1756
- const { showRemoveButton, showProgress, progressText, showPreview, showErrorStatus, dragSort, autoSubmit, showSubmitButton } = props
1757
- const { fileList, fileCacheMaps } = reactData
1758
- const isDisabled = $xeUpload.computeIsDisabled
1759
- const formReadonly = $xeUpload.computeFormReadonly
1760
- const imageOpts = $xeUpload.computeImageOpts
1761
- const imgStyle = $xeUpload.computeImgStyle
1762
- const optionSlot = slots.option
1763
- const actionSlot = slots.action
1764
- const cornerSlot = slots.corner
1765
-
1766
- const ons: Record<string, any> = {}
1767
- if (dragSort && currList.length > 1) {
1768
- ons.dragstart = $xeUpload.handleDragSortDragstartEvent
1769
- ons.dragover = $xeUpload.handleDragSortDragoverEvent
1770
- ons.dragend = $xeUpload.handleDragSortDragendEvent
1771
- }
1772
-
1773
- return currList.map((item, index) => {
1774
- const fileKey = $xeUpload.getFieldKey(item)
1775
- const cacheItem = fileCacheMaps[fileKey]
1776
- let isLoading = false
1777
- let isError = false
1778
- let isPending = false
1779
- if (cacheItem) {
1780
- isLoading = cacheItem.loading
1781
- isError = cacheItem.status === 'error'
1782
- isPending = cacheItem.status === 'pending'
1783
- }
1784
- return h('div', {
1785
- key: dragSort ? fileKey : index,
1786
- class: ['vxe-upload--image-item', {
1787
- 'is--preview': showPreview,
1788
- 'is--circle': imageOpts.circle,
1789
- 'is--loading': isLoading,
1790
- 'is--pending': isPending,
1791
- 'is--error': isError
1792
- }],
1793
- attrs: {
1794
- fileid: fileKey,
1795
- draggable: dragSort ? true : null
1796
- },
1797
- on: ons
1798
- }, optionSlot
1799
- ? getSlotVNs(optionSlot({ option: item, isMoreView, options: fileList }))
1800
- : [
1801
- h('div', {
1802
- class: 'vxe-upload--image-item-box',
1803
- style: isMoreView ? {} : imgStyle,
1804
- on: {
1805
- click (evnt: MouseEvent) {
1806
- if (!isLoading && !isError) {
1807
- $xeUpload.handlePreviewImageEvent(evnt, item, index)
1808
- }
1809
- }
1810
- }
1811
- }, [
1812
- isLoading && cacheItem
1813
- ? h('div', {
1814
- class: 'vxe-upload--image-item-loading'
1815
- }, [
1816
- h('div', {
1817
- class: 'vxe-upload--image-item-loading-icon'
1818
- }, [
1819
- h('i', {
1820
- class: getIcon().UPLOAD_LOADING
1821
- })
1822
- ]),
1823
- showProgress
1824
- ? h('div', {
1825
- class: 'vxe-upload--image-item-loading-text'
1826
- }, progressText ? XEUtils.toFormatString(`${XEUtils.isFunction(progressText) ? progressText({}) : progressText}`, { percent: cacheItem.percent }) : getI18n('vxe.upload.uploadProgress', [cacheItem.percent]))
1827
- : renderEmptyElement($xeUpload)
1828
- ])
1829
- : renderEmptyElement($xeUpload),
1830
- h('div', {
1831
- class: 'vxe-upload--image-item-img-wrapper',
1832
- attrs: {
1833
- title: getI18n('vxe.upload.viewItemTitle')
1834
- }
1835
- }, [
1836
- h('img', {
1837
- class: 'vxe-upload--image-item-img',
1838
- attrs: {
1839
- src: $xeUpload.getThumbnailFileUrl(item)
1840
- }
1841
- })
1842
- ]),
1843
- !isLoading && ((isError && showErrorStatus) || (isPending && showSubmitButton && !autoSubmit))
1844
- ? h('div', {
1845
- class: 'vxe-upload--image-item-rebtn'
1846
- }, [
1847
- h(VxeButtonComponent, {
1848
- props: {
1849
- icon: isError ? getIcon().UPLOAD_IMAGE_RE_UPLOAD : getIcon().UPLOAD_IMAGE_UPLOAD,
1850
- mode: 'text',
1851
- status: 'primary',
1852
- content: isError ? getI18n('vxe.upload.reUpload') : getI18n('vxe.upload.manualUpload')
1853
- },
1854
- on: {
1855
- click () {
1856
- $xeUpload.handleReUpload(item)
1857
- }
1858
- }
1859
- })
1860
- ])
1861
- : renderEmptyElement($xeUpload),
1862
- h('div', {
1863
- class: 'vxe-upload--image-item-btn-wrapper',
1864
- on: {
1865
- click (evnt: MouseEvent) {
1866
- evnt.stopPropagation()
1867
- }
1868
- }
1869
- }, actionSlot
1870
- ? getSlotVNs(actionSlot({ option: item, isMoreView, options: fileList, readonly: formReadonly }))
1871
- : [
1872
- cornerSlot
1873
- ? h('div', {
1874
- class: 'vxe-upload--file-item-action'
1875
- }, getSlotVNs(cornerSlot({ option: item, isMoreView, options: fileList, readonly: formReadonly })))
1876
- : renderEmptyElement($xeUpload),
1877
- showRemoveButton && !formReadonly && !isDisabled && !isLoading
1878
- ? h('div', {
1879
- class: 'vxe-upload--image-item-remove-btn',
1880
- on: {
1881
- click (evnt: MouseEvent) {
1882
- evnt.stopPropagation()
1883
- $xeUpload.removeFileEvent(evnt, item, index)
1884
- }
1885
- }
1886
- }, [
1887
- h('i', {
1888
- class: getIcon().UPLOAD_IMAGE_REMOVE
1889
- })
1890
- ])
1891
- : renderEmptyElement($xeUpload)
1892
- ])
1893
- ])
1894
- ])
1895
- })
1896
- },
1897
- renderImageAction (h: CreateElement, isMoreView: boolean) {
1898
- const $xeUpload = this
1899
- const props = $xeUpload
1900
- const slots = $xeUpload.$scopedSlots
1901
- const reactData = $xeUpload.reactData
1902
-
1903
- const { showUploadButton, buttonText, buttonIcon, showButtonText, showButtonIcon, autoHiddenButton } = props
1904
- const { fileList } = reactData
1905
- const formReadonly = $xeUpload.computeFormReadonly
1906
- const showTipText = $xeUpload.computedShowTipText
1907
- const defTipText = $xeUpload.computedDefTipText
1908
- const overCount = $xeUpload.computeOverCount
1909
- const imgStyle = $xeUpload.computeImgStyle
1910
- const defaultSlot = slots.default
1911
- const tipSlot = slots.tip || slots.hint
1912
-
1913
- if (formReadonly || !showUploadButton || (autoHiddenButton && overCount)) {
1914
- return renderEmptyElement($xeUpload)
1915
- }
1916
- return h('div', {
1917
- key: 'action',
1918
- class: 'vxe-upload--image-action'
1919
- }, [
1920
- h('div', {
1921
- class: 'vxe-upload--image-action-btn',
1922
- on: {
1923
- click: $xeUpload.clickEvent
1924
- }
1925
- }, defaultSlot
1926
- ? defaultSlot({ isMoreView, options: fileList, $upload: $xeUpload })
1927
- : [
1928
- h('div', {
1929
- class: 'vxe-upload--image-action-box',
1930
- style: isMoreView ? {} : imgStyle
1931
- }, [
1932
- showButtonIcon
1933
- ? h('div', {
1934
- class: 'vxe-upload--image-action-icon'
1935
- }, [
1936
- h('i', {
1937
- class: buttonIcon || getIcon().UPLOAD_IMAGE_ADD
1938
- })
1939
- ])
1940
- : renderEmptyElement($xeUpload),
1941
- isMoreView || showButtonText
1942
- ? h('div', {
1943
- class: 'vxe-upload--image-action-content'
1944
- }, buttonText ? `${XEUtils.isFunction(buttonText) ? buttonText({}) : buttonText}` : getI18n('vxe.upload.imgBtnText'))
1945
- : renderEmptyElement($xeUpload),
1946
- showTipText && (defTipText || tipSlot)
1947
- ? h('div', {
1948
- class: 'vxe-upload--image-action-hint'
1949
- }, tipSlot ? getSlotVNs(tipSlot({ isMoreView, options: fileList, $upload: $xeUpload })) : `${defTipText}`)
1950
- : renderEmptyElement($xeUpload)
1951
- ])
1952
- ])
1953
- ])
1954
- },
1955
- renderImageMode (h: CreateElement) {
1956
- const $xeUpload = this
1957
- const props = $xeUpload
1958
- const slots = $xeUpload.$scopedSlots
1959
- const reactData = $xeUpload.reactData
1960
-
1961
- const { showList, dragSort } = props
1962
- const { fileList, isDragMove } = reactData
1963
- const moreOpts = $xeUpload.computeMoreOpts
1964
- const moreBtnSlot = slots.moreButton || slots['more-button']
1965
-
1966
- const { maxCount, showMoreButton, moreButtonText } = moreOpts
1967
- let currList = fileList
1968
- let overMaxNum = 0
1969
- let isMoreMax = false
1970
- let isMiniMore = false
1971
- if (XEUtils.isNumber(maxCount) && fileList.length > maxCount) {
1972
- isMoreMax = true
1973
- isMiniMore = maxCount === 0
1974
- overMaxNum = fileList.length - maxCount
1975
- currList = fileList.slice(0, maxCount)
1976
- }
1977
-
1978
- return h('div', {
1979
- key: 'image',
1980
- class: 'vxe-upload--image-wrapper'
1981
- }, showList
1982
- ? [
1983
- dragSort
1984
- ? h('transition-group', {
1985
- attrs: {
1986
- name: `vxe-upload--drag-list${isDragMove ? '' : '-disabled'}`,
1987
- tag: 'div'
1988
- },
1989
- class: 'vxe-upload--image-list'
1990
- }, $xeUpload.renderImageItemList(h, currList, false).concat([
1991
- showMoreButton && overMaxNum
1992
- ? h('div', {
1993
- key: 'om',
1994
- class: 'vxe-upload--image-over-more'
1995
- }, moreBtnSlot
1996
- ? getSlotVNs(moreBtnSlot({ options: fileList }))
1997
- : [
1998
- h(VxeButtonComponent, {
1999
- props: {
2000
- mode: 'text',
2001
- content: moreButtonText ? (XEUtils.isFunction(moreButtonText) ? moreButtonText({ $upload: $xeUpload, options: fileList }) : XEUtils.toFormatString(moreButtonText, [fileList.length])) : getI18n(isMoreMax && isMiniMore ? 'vxe.upload.moreImgBtnText' : 'vxe.upload.moreBtnText', [fileList.length]),
2002
- status: 'primary'
2003
- },
2004
- on: {
2005
- click: $xeUpload.handleMoreEvent
2006
- }
2007
- })
2008
- ])
2009
- : renderEmptyElement($xeUpload),
2010
- $xeUpload.renderImageAction(h, false)
2011
- ]))
2012
- : h('div', {
2013
- class: 'vxe-upload--image-list'
2014
- }, $xeUpload.renderImageItemList(h, currList, false).concat([
2015
- showMoreButton && overMaxNum
2016
- ? h('div', {
2017
- class: 'vxe-upload--image-over-more'
2018
- }, moreBtnSlot
2019
- ? getSlotVNs(moreBtnSlot({ options: fileList }))
2020
- : [
2021
- h(VxeButtonComponent, {
2022
- props: {
2023
- mode: 'text',
2024
- content: moreButtonText ? (XEUtils.isFunction(moreButtonText) ? moreButtonText({ $upload: $xeUpload, options: fileList }) : XEUtils.toFormatString(moreButtonText, [fileList.length])) : getI18n(isMoreMax && isMiniMore ? 'vxe.upload.moreImgBtnText' : 'vxe.upload.moreBtnText', [fileList.length]),
2025
- status: 'primary'
2026
- },
2027
- on: {
2028
- click: $xeUpload.handleMoreEvent
2029
- }
2030
- })
2031
- ])
2032
- : renderEmptyElement($xeUpload),
2033
- $xeUpload.renderImageAction(h, false)
2034
- ]))
2035
- ]
2036
- : [
2037
- h('div', {
2038
- class: 'vxe-upload--image-list'
2039
- }, [
2040
- $xeUpload.renderImageAction(h, false)
2041
- ])
2042
- ])
2043
- },
2044
- renderVN (h: CreateElement): VNode {
2045
- const $xeUpload = this
2046
- const props = $xeUpload
2047
- const reactData = $xeUpload.reactData
2048
-
2049
- const { showErrorStatus, dragToUpload, pasteToUpload, dragSort, dragPlaceholder } = props
2050
- const { isDragUploadStatus, showMorePopup, isActivated, dragIndex } = reactData
2051
- const vSize = $xeUpload.computeSize
2052
- const isDisabled = $xeUpload.computeIsDisabled
2053
- const formReadonly = $xeUpload.computeFormReadonly
2054
- const isImage = $xeUpload.computeIsImage
2055
-
2056
- const ons: Record<string, any> = {}
2057
- if (dragToUpload && dragIndex === -1) {
2058
- ons.dragover = $xeUpload.handleUploadDragoverEvent
2059
- ons.dragleave = $xeUpload.handleUploadDragleaveEvent
2060
- ons.drop = $xeUpload.handleUploadDropEvent
2061
- }
2062
-
2063
- return h('div', {
2064
- ref: 'refElem',
2065
- class: ['vxe-upload', {
2066
- [`size--${vSize}`]: vSize,
2067
- 'is--active': isActivated,
2068
- 'is--readonly': formReadonly,
2069
- 'is--disabled': isDisabled,
2070
- 'is--paste': pasteToUpload,
2071
- 'show--error': showErrorStatus,
2072
- 'is--drag': isDragUploadStatus
2073
- }],
2074
- on: ons
2075
- }, [
2076
- isImage ? $xeUpload.renderImageMode(h) : $xeUpload.rendeFileMode(h),
2077
- dragSort
2078
- ? h('div', {
2079
- ref: 'refDragLineElem',
2080
- class: 'vxe-upload--drag-line'
2081
- })
2082
- : renderEmptyElement($xeUpload),
2083
- isDragUploadStatus && !showMorePopup
2084
- ? h('div', {
2085
- class: 'vxe-upload--drag-placeholder'
2086
- }, dragPlaceholder || getI18n('vxe.upload.dragPlaceholder'))
2087
- : renderEmptyElement($xeUpload)
2088
- ])
2089
- }
2090
- },
2091
- created () {
2092
- const $xeUpload = this
2093
-
2094
- $xeUpload.updateFileList()
2095
- },
2096
- mounted () {
2097
- const $xeUpload = this
2098
- const props = $xeUpload
2099
-
2100
- if (props.multiple && props.singleMode) {
2101
- errLog('vxe.error.errConflicts', ['[upload] multiple', 'single-mode'])
2102
- }
2103
- if (props.imageStyle) {
2104
- warnLog('vxe.error.delProp', ['[upload] image-style', 'image-config'])
2105
- }
2106
-
2107
- if (props.dragSort) {
2108
- initTpImg()
2109
- }
2110
- globalEvents.on($xeUpload, 'paste', $xeUpload.handleGlobalPasteEvent)
2111
- globalEvents.on($xeUpload, 'click', $xeUpload.handleGlobalClickEvent)
2112
- globalEvents.on($xeUpload, 'blur', $xeUpload.handleGlobalBlurEvent)
2113
- },
2114
- beforeDestroy () {
2115
- const $xeUpload = this
2116
- const reactData = $xeUpload.reactData
2117
- const internalData = $xeUpload.internalData
2118
-
2119
- reactData.isDragUploadStatus = false
2120
- globalEvents.off($xeUpload, 'paste')
2121
- globalEvents.off($xeUpload, 'click')
2122
- globalEvents.off($xeUpload, 'blur')
2123
- XEUtils.assign(reactData, createReactData())
2124
- XEUtils.assign(internalData, createInternalData())
2125
- },
2126
- render (this: any, h) {
2127
- return this.renderVN(h)
2128
- }
2129
- }) /* define-vxe-component end */
1
+ import { PropType, CreateElement, VNode } from 'vue'
2
+ import { defineVxeComponent } from '../../ui/src/comp'
3
+ import XEUtils from 'xe-utils'
4
+ import { VxeUI, getConfig, getI18n, getIcon, globalMixins, createEvent, globalEvents, renderEmptyElement } from '../../ui'
5
+ import { getSlotVNs } from '../../ui/src/vn'
6
+ import { errLog, warnLog } from '../../ui/src/log'
7
+ import { initTpImg, getTpImg, getEventTargetNode, toCssUnit } from '../../ui/src/dom'
8
+ import { readLocalFile } from './util'
9
+ import VxeButtonComponent from '../../button/src/button'
10
+
11
+ import type { VxeUploadDefines, VxeUploadConstructor, VxeUploadPropTypes, UploadReactData, UploadInternalData, VxeUploadEmits, VxeComponentSizeType, VxeFormDefines, VxeFormConstructor, VxeFormPrivateMethods, ValueOf, VxeComponentEventParams } from '../../../types'
12
+ import type { VxeTableConstructor, VxeTablePrivateMethods } from '../../../types/components/table'
13
+
14
+ function getUniqueKey () {
15
+ return XEUtils.uniqueId()
16
+ }
17
+
18
+ function handleTransferFiles (items: DataTransferItemList) {
19
+ const files: File[] = []
20
+ XEUtils.arrayEach(items, item => {
21
+ const file = item.getAsFile()
22
+ if (file) {
23
+ files.push(file)
24
+ }
25
+ })
26
+ return files
27
+ }
28
+
29
+ function showDropTip ($xeUpload: VxeUploadConstructor, evnt: DragEvent, dragEl: HTMLElement, dragPos: string) {
30
+ const { xID } = $xeUpload
31
+
32
+ const reactData = $xeUpload.reactData
33
+
34
+ const { showMorePopup } = reactData
35
+ const el = $xeUpload.$refs.refElem as HTMLDivElement
36
+ const popupEl = document.getElementById(`refPopupElem${xID}`) as HTMLDivElement
37
+ const wrapperEl = showMorePopup ? popupEl : el
38
+ if (!wrapperEl) {
39
+ return
40
+ }
41
+ const wrapperRect = wrapperEl.getBoundingClientRect()
42
+ const ddLineEl = $xeUpload.$refs.refDragLineElem as HTMLDivElement
43
+ const mdLineEl = document.getElementById(`refModalDragLineElem${xID}`) as HTMLDivElement
44
+ const currDLineEl = showMorePopup ? mdLineEl : ddLineEl
45
+ if (currDLineEl) {
46
+ const dragRect = dragEl.getBoundingClientRect()
47
+ currDLineEl.style.display = 'block'
48
+ currDLineEl.style.top = `${Math.max(1, dragRect.y - wrapperRect.y)}px`
49
+ currDLineEl.style.left = `${Math.max(1, dragRect.x - wrapperRect.x)}px`
50
+ currDLineEl.style.height = `${dragRect.height}px`
51
+ currDLineEl.style.width = `${dragRect.width - 1}px`
52
+ currDLineEl.setAttribute('drag-pos', dragPos)
53
+ }
54
+ }
55
+
56
+ function hideDropTip ($xeUpload: VxeUploadConstructor) {
57
+ const { xID } = $xeUpload
58
+
59
+ const ddLineEl = $xeUpload.$refs.refDragLineElem as HTMLDivElement
60
+ const mdLineEl = document.getElementById(`refModalDragLineElem${xID}`) as HTMLDivElement
61
+ if (ddLineEl) {
62
+ ddLineEl.style.display = ''
63
+ }
64
+ if (mdLineEl) {
65
+ mdLineEl.style.display = ''
66
+ }
67
+ }
68
+
69
+ function createReactData (): UploadReactData {
70
+ return {
71
+ isDragUploadStatus: false,
72
+ showMorePopup: false,
73
+ isActivated: false,
74
+ fileList: [],
75
+ fileCacheMaps: {},
76
+ isDragMove: false,
77
+ dragIndex: -1,
78
+ dragTipText: ''
79
+ }
80
+ }
81
+
82
+ function createInternalData (): UploadInternalData {
83
+ return {
84
+ moreId: XEUtils.uniqueId('upload'),
85
+ imagePreviewTypes: ['jpg', 'jpeg', 'png', 'gif'],
86
+ prevDragIndex: -1
87
+ // prevDragPos: ''
88
+ }
89
+ }
90
+
91
+ export default /* define-vxe-component start */ defineVxeComponent({
92
+ name: 'VxeUpload',
93
+ model: {
94
+ prop: 'value',
95
+ event: 'modelValue'
96
+ },
97
+ mixins: [
98
+ globalMixins.sizeMixin
99
+ ],
100
+ props: {
101
+ value: [Array, String, Object] as PropType<VxeUploadPropTypes.ModelValue>,
102
+ showList: {
103
+ type: Boolean as PropType<VxeUploadPropTypes.ShowList>,
104
+ default: () => getConfig().upload.showList
105
+ },
106
+ moreConfig: Object as PropType<VxeUploadPropTypes.MoreConfig>,
107
+ readonly: {
108
+ type: Boolean as PropType<VxeUploadPropTypes.Readonly>,
109
+ default: null
110
+ },
111
+ disabled: {
112
+ type: Boolean as PropType<VxeUploadPropTypes.Disabled>,
113
+ default: null
114
+ },
115
+ autoSubmit: {
116
+ type: Boolean as PropType<VxeUploadPropTypes.AutoSubmit>,
117
+ default: () => getConfig().upload.autoSubmit
118
+ },
119
+ mode: {
120
+ type: String as PropType<VxeUploadPropTypes.Mode>,
121
+ default: () => getConfig().upload.mode
122
+ },
123
+ imageTypes: {
124
+ type: Array as PropType<VxeUploadPropTypes.ImageTypes>,
125
+ default: () => XEUtils.clone(getConfig().upload.imageTypes, true)
126
+ },
127
+ imageConfig: {
128
+ type: Object as PropType<VxeUploadPropTypes.ImageConfig>,
129
+ default: () => XEUtils.clone(getConfig().upload.imageConfig, true)
130
+ },
131
+ /**
132
+ * 已废弃,被 image-config 替换
133
+ * @deprecated
134
+ */
135
+ imageStyle: {
136
+ type: Object as PropType<VxeUploadPropTypes.ImageStyle>,
137
+ default: () => XEUtils.clone(getConfig().upload.imageStyle, true)
138
+ },
139
+ fileTypes: {
140
+ type: Array as PropType<VxeUploadPropTypes.FileTypes>,
141
+ default: () => XEUtils.clone(getConfig().upload.fileTypes, true)
142
+ },
143
+ dragSort: Boolean as PropType<VxeUploadPropTypes.DragSort>,
144
+ dragToUpload: {
145
+ type: Boolean as PropType<VxeUploadPropTypes.DragToUpload>,
146
+ default: () => XEUtils.clone(getConfig().upload.dragToUpload, true)
147
+ },
148
+ dragPlaceholder: {
149
+ type: String as PropType<VxeUploadPropTypes.DragPlaceholder>,
150
+ default: () => getConfig().upload.dragPlaceholder
151
+ },
152
+ pasteToUpload: {
153
+ type: Boolean as PropType<VxeUploadPropTypes.PasteToUpload>,
154
+ default: () => XEUtils.clone(getConfig().upload.pasteToUpload, true)
155
+ },
156
+ keyField: String as PropType<VxeUploadPropTypes.KeyField>,
157
+ singleMode: Boolean as PropType<VxeUploadPropTypes.SingleMode>,
158
+ urlMode: Boolean as PropType<VxeUploadPropTypes.UrlMode>,
159
+ urlArgs: {
160
+ type: Boolean as PropType<VxeUploadPropTypes.UrlArgs>,
161
+ default: () => getConfig().upload.urlArgs
162
+ },
163
+ multiple: Boolean as PropType<VxeUploadPropTypes.Multiple>,
164
+ limitSize: {
165
+ type: [String, Number] as PropType<VxeUploadPropTypes.LimitSize>,
166
+ default: () => getConfig().upload.limitSize
167
+ },
168
+ showLimitSize: {
169
+ type: Boolean as PropType<VxeUploadPropTypes.ShowLimitSize>,
170
+ default: () => getConfig().upload.showLimitSize
171
+ },
172
+ limitSizeText: {
173
+ type: [String, Number, Function] as PropType<VxeUploadPropTypes.LimitSizeText>,
174
+ default: () => getConfig().upload.limitSizeText
175
+ },
176
+ limitCount: {
177
+ type: [String, Number] as PropType<VxeUploadPropTypes.LimitCount>,
178
+ default: () => getConfig().upload.limitCount
179
+ },
180
+ showLimitCount: {
181
+ type: Boolean as PropType<VxeUploadPropTypes.ShowLimitCount>,
182
+ default: () => getConfig().upload.showLimitCount
183
+ },
184
+ limitCountText: {
185
+ type: [String, Number, Function] as PropType<VxeUploadPropTypes.LimitCountText>,
186
+ default: () => getConfig().upload.limitCountText
187
+ },
188
+ nameField: {
189
+ type: String as PropType<VxeUploadPropTypes.NameField>,
190
+ default: () => getConfig().upload.nameField
191
+ },
192
+ typeField: {
193
+ type: String as PropType<VxeUploadPropTypes.TypeField>,
194
+ default: () => getConfig().upload.typeField
195
+ },
196
+ urlField: {
197
+ type: String as PropType<VxeUploadPropTypes.UrlField>,
198
+ default: () => getConfig().upload.urlField
199
+ },
200
+ sizeField: {
201
+ type: String as PropType<VxeUploadPropTypes.SizeField>,
202
+ default: () => getConfig().upload.sizeField
203
+ },
204
+ showErrorStatus: {
205
+ type: Boolean as PropType<VxeUploadPropTypes.ShowErrorStatus>,
206
+ default: () => getConfig().upload.showErrorStatus
207
+ },
208
+ showProgress: {
209
+ type: Boolean as PropType<VxeUploadPropTypes.ShowProgress>,
210
+ default: () => getConfig().upload.showProgress
211
+ },
212
+ progressText: {
213
+ type: [String, Number, Function] as PropType<VxeUploadPropTypes.ProgressText>,
214
+ default: () => getConfig().upload.progressText
215
+ },
216
+ previewImageConfig: Object as PropType<VxeUploadPropTypes.PreviewImageConfig>,
217
+ showSubmitButton: Boolean as PropType<VxeUploadPropTypes.ShowSubmitButton>,
218
+ autoHiddenButton: {
219
+ type: Boolean as PropType<VxeUploadPropTypes.AutoHiddenButton>,
220
+ default: () => getConfig().upload.autoHiddenButton
221
+ },
222
+ showUploadButton: {
223
+ type: Boolean as PropType<VxeUploadPropTypes.ShowUploadButton>,
224
+ default: () => getConfig().upload.showUploadButton
225
+ },
226
+ buttonText: {
227
+ type: [String, Number, Function] as PropType<VxeUploadPropTypes.ButtonText>,
228
+ default: () => getConfig().upload.buttonText
229
+ },
230
+ buttonIcon: {
231
+ type: String as PropType<VxeUploadPropTypes.ButtonIcon>,
232
+ default: () => getConfig().upload.buttonIcon
233
+ },
234
+ showButtonText: {
235
+ type: Boolean as PropType<VxeUploadPropTypes.ShowButtonText>,
236
+ default: () => getConfig().upload.showButtonText
237
+ },
238
+ showButtonIcon: {
239
+ type: Boolean as PropType<VxeUploadPropTypes.ShowButtonIcon>,
240
+ default: () => getConfig().upload.showButtonIcon
241
+ },
242
+ showRemoveButton: {
243
+ type: Boolean as PropType<VxeUploadPropTypes.ShowRemoveButton>,
244
+ default: () => getConfig().upload.showRemoveButton
245
+ },
246
+ showDownloadButton: {
247
+ type: Boolean as PropType<VxeUploadPropTypes.ShowDownloadButton>,
248
+ default: () => getConfig().upload.showDownloadButton
249
+ },
250
+ showPreview: {
251
+ type: Boolean as PropType<VxeUploadPropTypes.ShowPreview>,
252
+ default: () => getConfig().upload.showPreview
253
+ },
254
+ showTip: {
255
+ type: Boolean as PropType<VxeUploadPropTypes.ShowTip>,
256
+ default: () => getConfig().upload.showTip
257
+ },
258
+ maxSimultaneousUploads: {
259
+ type: Number as PropType<VxeUploadPropTypes.MaxSimultaneousUploads>,
260
+ default: () => getConfig().upload.maxSimultaneousUploads
261
+ },
262
+ tipText: [String, Number, Function] as PropType<VxeUploadPropTypes.TipText>,
263
+ hintText: String as PropType<VxeUploadPropTypes.HintText>,
264
+ previewMethod: Function as PropType<VxeUploadPropTypes.PreviewMethod>,
265
+ beforeSelectMethod: Function as PropType<VxeUploadPropTypes.BeforeSelectMethod>,
266
+ uploadMethod: Function as PropType<VxeUploadPropTypes.UploadMethod>,
267
+ beforeRemoveMethod: Function as PropType<VxeUploadPropTypes.BeforeRemoveMethod>,
268
+ removeMethod: Function as PropType<VxeUploadPropTypes.RemoveMethod>,
269
+ beforeDownloadMethod: Function as PropType<VxeUploadPropTypes.BeforeDownloadMethod>,
270
+ downloadMethod: Function as PropType<VxeUploadPropTypes.DownloadMethod>,
271
+ getUrlMethod: Function as PropType<VxeUploadPropTypes.GetUrlMethod>,
272
+ getThumbnailUrlMethod: Function as PropType<VxeUploadPropTypes.GetThumbnailUrlMethod>,
273
+ size: {
274
+ type: String as PropType<VxeUploadPropTypes.Size>,
275
+ default: () => getConfig().upload.size || getConfig().size
276
+ }
277
+ },
278
+ inject: {
279
+ $xeForm: {
280
+ default: null
281
+ },
282
+ formItemInfo: {
283
+ from: 'xeFormItemInfo',
284
+ default: null
285
+ },
286
+ $xeTable: {
287
+ default: null
288
+ }
289
+ },
290
+ data () {
291
+ const xID = XEUtils.uniqueId()
292
+ const reactData = createReactData()
293
+ const internalData = createInternalData()
294
+ return {
295
+ xID,
296
+ reactData,
297
+ internalData
298
+ }
299
+ },
300
+ computed: {
301
+ ...({} as {
302
+ computeSize(): VxeComponentSizeType
303
+ $xeForm(): (VxeFormConstructor & VxeFormPrivateMethods) | null
304
+ formItemInfo(): VxeFormDefines.ProvideItemInfo | null,
305
+ $xeTable(): (VxeTableConstructor & VxeTablePrivateMethods) | null
306
+ }),
307
+ computeFormReadonly () {
308
+ const $xeUpload = this
309
+ const props = $xeUpload
310
+ const $xeForm = $xeUpload.$xeForm
311
+
312
+ const { readonly } = props
313
+ if (readonly === null) {
314
+ if ($xeForm) {
315
+ return $xeForm.readonly
316
+ }
317
+ return false
318
+ }
319
+ return readonly
320
+ },
321
+ computeIsDisabled () {
322
+ const $xeUpload = this
323
+ const props = $xeUpload
324
+ const $xeForm = $xeUpload.$xeForm
325
+
326
+ const { disabled } = props
327
+ if (disabled === null) {
328
+ if ($xeForm) {
329
+ return $xeForm.disabled
330
+ }
331
+ return false
332
+ }
333
+ return disabled
334
+ },
335
+ computeKeyField () {
336
+ const $xeUpload = this
337
+ const props = $xeUpload
338
+
339
+ return props.keyField || '_X_KEY'
340
+ },
341
+ computeIsImage () {
342
+ const $xeUpload = this
343
+ const props = $xeUpload
344
+
345
+ return props.mode === 'image'
346
+ },
347
+ computeNameProp () {
348
+ const $xeUpload = this
349
+ const props = $xeUpload
350
+
351
+ return props.nameField || 'name'
352
+ },
353
+ computeTypeProp () {
354
+ const $xeUpload = this
355
+ const props = $xeUpload
356
+
357
+ return props.typeField || 'type'
358
+ },
359
+ computeUrlProp () {
360
+ const $xeUpload = this
361
+ const props = $xeUpload
362
+
363
+ return props.urlField || 'url'
364
+ },
365
+ computeSizeProp () {
366
+ const $xeUpload = this
367
+ const props = $xeUpload
368
+
369
+ return props.sizeField || 'size'
370
+ },
371
+ computeLimitMaxSize () {
372
+ const $xeUpload = this
373
+ const props = $xeUpload
374
+
375
+ return XEUtils.toNumber(props.limitSize) * 1024 * 1024
376
+ },
377
+ computeLimitMaxCount () {
378
+ const $xeUpload = this
379
+ const props = $xeUpload
380
+
381
+ return props.multiple ? XEUtils.toNumber(props.limitCount) : 1
382
+ },
383
+ computePreviewImageOpts () {
384
+ const $xeUpload = this
385
+ const props = $xeUpload
386
+
387
+ const { showDownloadButton } = props
388
+ return Object.assign({
389
+ showDownloadButton
390
+ }, getConfig().upload.previewImageConfig, props.previewImageConfig)
391
+ },
392
+ computeOverCount () {
393
+ const $xeUpload = this
394
+ const props = $xeUpload
395
+ const reactData = $xeUpload.reactData as UploadReactData
396
+
397
+ const { multiple } = props
398
+ const { fileList } = reactData
399
+ const limitMaxCount = $xeUpload.computeLimitMaxCount as number
400
+ if (multiple) {
401
+ if (limitMaxCount) {
402
+ return fileList.length >= limitMaxCount
403
+ }
404
+ return true
405
+ }
406
+ return fileList.length >= 1
407
+ },
408
+ computeLimitSizeUnit () {
409
+ const $xeUpload = this
410
+ const props = $xeUpload
411
+
412
+ const limitSize = XEUtils.toNumber(props.limitSize)
413
+ if (limitSize) {
414
+ if (limitSize > 1048576) {
415
+ return `${limitSize / 1048576}T`
416
+ }
417
+ if (limitSize > 1024) {
418
+ return `${limitSize / 1024}G`
419
+ }
420
+ return `${limitSize}M`
421
+ }
422
+ return ''
423
+ },
424
+ computedShowTipText () {
425
+ const $xeUpload = this
426
+ const props = $xeUpload
427
+
428
+ const { showTip, tipText } = props
429
+ if (XEUtils.isBoolean(showTip)) {
430
+ return showTip
431
+ }
432
+ const defShowTip = getConfig().upload.showTip
433
+ if (XEUtils.isBoolean(defShowTip)) {
434
+ return defShowTip
435
+ }
436
+ if (tipText) {
437
+ return true
438
+ }
439
+ return false
440
+ },
441
+ computedDefTipText () {
442
+ const $xeUpload = this
443
+ const props = $xeUpload
444
+
445
+ const { limitSize, fileTypes, multiple, limitCount } = props
446
+ const tipText = props.tipText || props.hintText
447
+ const isImage = $xeUpload.computeIsImage
448
+ const limitSizeUnit = $xeUpload.computeLimitSizeUnit
449
+ if (XEUtils.isString(tipText)) {
450
+ return tipText
451
+ }
452
+ if (XEUtils.isFunction(tipText)) {
453
+ return `${tipText({})}`
454
+ }
455
+ const defTips: string[] = []
456
+ if (isImage) {
457
+ if (multiple && limitCount) {
458
+ defTips.push(getI18n('vxe.upload.imgCountHint', [limitCount]))
459
+ }
460
+ if (limitSize && limitSizeUnit) {
461
+ defTips.push(getI18n('vxe.upload.imgSizeHint', [limitSizeUnit]))
462
+ }
463
+ } else {
464
+ if (fileTypes && fileTypes.length) {
465
+ defTips.push(getI18n('vxe.upload.fileTypeHint', [fileTypes.join('/')]))
466
+ }
467
+ if (limitSize && limitSizeUnit) {
468
+ defTips.push(getI18n('vxe.upload.fileSizeHint', [limitSizeUnit]))
469
+ }
470
+ if (multiple && limitCount) {
471
+ defTips.push(getI18n('vxe.upload.fileCountHint', [limitCount]))
472
+ }
473
+ }
474
+ return defTips.join(getI18n('vxe.base.comma'))
475
+ },
476
+ computeImageOpts () {
477
+ const $xeUpload = this
478
+ const props = $xeUpload
479
+
480
+ return Object.assign({}, props.imageConfig || props.imageStyle)
481
+ },
482
+ computeImgStyle () {
483
+ const $xeUpload = this
484
+
485
+ const imageOpts = $xeUpload.computeImageOpts
486
+ const { width, height } = imageOpts
487
+ const stys: Record<string, string> = {}
488
+ if (width) {
489
+ stys.width = toCssUnit(width)
490
+ }
491
+ if (height) {
492
+ stys.height = toCssUnit(height)
493
+ }
494
+ return stys
495
+ },
496
+ computeMoreOpts () {
497
+ const $xeUpload = this
498
+ const props = $xeUpload
499
+
500
+ return Object.assign({ showMoreButton: true }, props.moreConfig)
501
+ }
502
+ },
503
+ watch: {
504
+ value () {
505
+ const $xeUpload = this
506
+ $xeUpload.updateFileList()
507
+ }
508
+ },
509
+ methods: {
510
+ //
511
+ // Method
512
+ //
513
+ dispatchEvent (type: ValueOf<VxeUploadEmits>, params: Record<string, any>, evnt: Event | null) {
514
+ const $xeUpload = this
515
+ $xeUpload.$emit(type, createEvent(evnt, { $upload: $xeUpload }, params))
516
+ },
517
+ emitModel (value: any) {
518
+ const $xeUpload = this
519
+
520
+ const { _events } = $xeUpload as any
521
+ if (_events && _events.modelValue) {
522
+ $xeUpload.$emit('modelValue', value)
523
+ } else {
524
+ $xeUpload.$emit('model-value', value)
525
+ }
526
+ },
527
+ choose () {
528
+ const $xeUpload = this
529
+ return $xeUpload.handleChoose(null)
530
+ },
531
+ getPendingFiles () {
532
+ const $xeUpload = this
533
+ const reactData = $xeUpload.reactData
534
+
535
+ const { fileList, fileCacheMaps } = reactData
536
+ const pendingFiles: File[] = []
537
+ fileList.forEach(item => {
538
+ const fileKey = $xeUpload.getFieldKey(item)
539
+ const cacheItem = fileCacheMaps[fileKey]
540
+ if (cacheItem && cacheItem.status === 'pending') {
541
+ pendingFiles.push(cacheItem.file)
542
+ }
543
+ })
544
+ return pendingFiles
545
+ },
546
+ submit (isFull?: boolean) {
547
+ const $xeUpload = this
548
+ const props = $xeUpload
549
+ const reactData = $xeUpload.reactData
550
+
551
+ const { maxSimultaneousUploads } = props
552
+ const msNum = XEUtils.toNumber(maxSimultaneousUploads || 1) || 1
553
+ const { fileList, fileCacheMaps } = reactData
554
+ const allPendingList = fileList.filter(item => {
555
+ const fileKey = $xeUpload.getFieldKey(item)
556
+ const cacheItem = fileCacheMaps[fileKey]
557
+ return cacheItem && (cacheItem.status === 'pending' || (isFull && cacheItem.status === 'error'))
558
+ })
559
+
560
+ const handleSubmit = (item: VxeUploadDefines.FileObjItem): Promise<void> => {
561
+ const fileKey = $xeUpload.getFieldKey(item)
562
+ const cacheItem = fileCacheMaps[fileKey]
563
+ if (cacheItem) {
564
+ const file = cacheItem.file
565
+ if (file && (cacheItem.status === 'pending' || (isFull && cacheItem.status === 'error'))) {
566
+ cacheItem.loading = true
567
+ cacheItem.percent = 0
568
+ return $xeUpload.handleUploadResult(item, file).then(handleNextSubmit)
569
+ }
570
+ }
571
+ return handleNextSubmit()
572
+ }
573
+
574
+ const handleNextSubmit = (): Promise<void> => {
575
+ if (allPendingList.length) {
576
+ const item = allPendingList[0]
577
+ allPendingList.splice(0, 1)
578
+ return handleSubmit(item).then(handleNextSubmit)
579
+ }
580
+ return Promise.resolve()
581
+ }
582
+
583
+ return Promise.all(allPendingList.splice(0, msNum).map(handleSubmit)).then(() => {
584
+ // 完成
585
+ })
586
+ },
587
+ getMoreVisible () {
588
+ const $xeUpload = this
589
+ const reactData = $xeUpload.reactData
590
+
591
+ return reactData.showMorePopup
592
+ },
593
+ openMore () {
594
+ const $xeUpload = this
595
+
596
+ $xeUpload.handleMoreEvent({ $event: new Event('click') })
597
+ return $xeUpload.$nextTick()
598
+ },
599
+ openMoreByEvent (evnt: Event) {
600
+ const $xeUpload = this
601
+
602
+ $xeUpload.handleMoreEvent({ $event: evnt })
603
+ return $xeUpload.$nextTick()
604
+ },
605
+ closeMore () {
606
+ const $xeUpload = this
607
+ const internalData = $xeUpload.internalData
608
+
609
+ if (VxeUI.modal) {
610
+ VxeUI.modal.close(internalData.moreId)
611
+ }
612
+ return $xeUpload.$nextTick()
613
+ },
614
+ getFieldKey (item: VxeUploadDefines.FileObjItem) {
615
+ const $xeUpload = this
616
+
617
+ const keyField = $xeUpload.computeKeyField
618
+ return item[keyField]
619
+ },
620
+ updateFileList () {
621
+ const $xeUpload = this
622
+ const props = $xeUpload
623
+ const reactData = $xeUpload.reactData
624
+
625
+ const { value, multiple } = props
626
+ const formReadonly = $xeUpload.computeFormReadonly
627
+ const keyField = $xeUpload.computeKeyField
628
+ const nameProp = $xeUpload.computeNameProp
629
+ const typeProp = $xeUpload.computeTypeProp
630
+ const urlProp = $xeUpload.computeUrlProp
631
+ const sizeProp = $xeUpload.computeSizeProp
632
+ const fileList = value
633
+ ? (value ? (XEUtils.isArray(value) ? value : [value]) : []).map(item => {
634
+ if (!item || XEUtils.isString(item)) {
635
+ const url = `${item || ''}`
636
+ const urlObj = XEUtils.parseUrl(item)
637
+ const name = (urlObj ? urlObj.searchQuery[nameProp] : '') || $xeUpload.parseFileName(url)
638
+ return {
639
+ [nameProp]: name,
640
+ [typeProp]: (urlObj ? urlObj.searchQuery[typeProp] : '') || $xeUpload.parseFileType(name),
641
+ [urlProp]: url,
642
+ [sizeProp]: XEUtils.toNumber(urlObj ? urlObj.searchQuery[sizeProp] : 0) || 0,
643
+ [keyField]: getUniqueKey()
644
+ }
645
+ }
646
+ const name = item[nameProp] || ''
647
+ item[nameProp] = name
648
+ item[typeProp] = item[typeProp] || $xeUpload.parseFileType(name)
649
+ item[urlProp] = item[urlProp] || ''
650
+ item[sizeProp] = item[sizeProp] || 0
651
+ item[keyField] = item[keyField] || getUniqueKey()
652
+ return item
653
+ })
654
+ : []
655
+ reactData.fileList = (formReadonly || multiple) ? fileList : (fileList.slice(0, 1))
656
+ },
657
+ parseFileName (url: string) {
658
+ return decodeURIComponent(`${url || ''}`).split('/').pop() || ''
659
+ },
660
+ parseFileType (name: string) {
661
+ const index = name.lastIndexOf('.')
662
+ if (index > 0) {
663
+ return name.substring(index + 1).toLowerCase()
664
+ }
665
+ return ''
666
+ },
667
+ handleChange (value: VxeUploadDefines.FileObjItem[]) {
668
+ const $xeUpload = this
669
+ const props = $xeUpload
670
+
671
+ const { singleMode, urlMode, urlArgs } = props
672
+ const urlProp = $xeUpload.computeUrlProp
673
+ const nameProp = $xeUpload.computeNameProp
674
+ let restList = value ? value.slice(0) : []
675
+ if (urlMode) {
676
+ restList = restList.map(item => {
677
+ const url = item[urlProp]
678
+ if (url && urlArgs) {
679
+ const urlObj = XEUtils.parseUrl(url)
680
+ if (!urlObj.searchQuery[nameProp]) {
681
+ if (url.indexOf('blob:') === -1) {
682
+ return `${url}${url.indexOf('?') === -1 ? '?' : '&'}${encodeURIComponent(item[nameProp] || '')}`
683
+ }
684
+ }
685
+ }
686
+ return url
687
+ })
688
+ }
689
+ $xeUpload.emitModel(singleMode ? (restList[0] || null) : restList)
690
+ },
691
+ getThumbnailFileUrl (item: VxeUploadDefines.FileObjItem) {
692
+ const $xeUpload = this
693
+ const props = $xeUpload
694
+
695
+ const getThumbnailUrlFn = props.getThumbnailUrlMethod || getConfig().upload.getThumbnailUrlMethod
696
+ if (getThumbnailUrlFn) {
697
+ return getThumbnailUrlFn({
698
+ $upload: $xeUpload,
699
+ option: item
700
+ })
701
+ }
702
+ return $xeUpload.getFileUrl(item)
703
+ },
704
+ getFileUrl (item: VxeUploadDefines.FileObjItem) {
705
+ const $xeUpload = this
706
+ const props = $xeUpload
707
+
708
+ const getUrlFn = props.getUrlMethod || getConfig().upload.getUrlMethod
709
+ const urlProp = $xeUpload.computeUrlProp
710
+ return getUrlFn
711
+ ? getUrlFn({
712
+ $upload: $xeUpload,
713
+ option: item
714
+ })
715
+ : item[urlProp]
716
+ },
717
+ handleDefaultFilePreview (item: VxeUploadDefines.FileObjItem) {
718
+ const $xeUpload = this
719
+ const props = $xeUpload
720
+ const internalData = $xeUpload.internalData
721
+
722
+ const { imageTypes } = props
723
+ const typeProp = $xeUpload.computeTypeProp
724
+ const previewImageOpts = $xeUpload.computePreviewImageOpts
725
+ const beforeDownloadFn = props.beforeDownloadMethod || getConfig().upload.beforeDownloadMethod
726
+ const { imagePreviewTypes } = internalData
727
+ // 如果是预览图片
728
+ if (imagePreviewTypes.concat(imageTypes || []).some(type => `${type}`.toLowerCase() === `${item[typeProp]}`.toLowerCase())) {
729
+ if (VxeUI.previewImage) {
730
+ VxeUI.previewImage({
731
+ ...previewImageOpts,
732
+ urlList: [$xeUpload.getFileUrl(item)],
733
+ beforeDownloadMethod: beforeDownloadFn
734
+ ? () => {
735
+ return beforeDownloadFn({
736
+ $upload: $xeUpload,
737
+ option: item
738
+ })
739
+ }
740
+ : undefined
741
+ })
742
+ }
743
+ }
744
+ },
745
+ handlePreviewFileEvent (evnt: MouseEvent, item: VxeUploadDefines.FileObjItem) {
746
+ const $xeUpload = this
747
+ const props = $xeUpload
748
+
749
+ const previewFn = props.previewMethod || getConfig().upload.previewMethod
750
+ if (props.showPreview) {
751
+ if (previewFn) {
752
+ previewFn({
753
+ $upload: $xeUpload,
754
+ option: item
755
+ })
756
+ } else {
757
+ $xeUpload.handleDefaultFilePreview(item)
758
+ }
759
+ }
760
+ },
761
+ handlePreviewImageEvent (evnt: MouseEvent, item: VxeUploadDefines.FileObjItem, index: number) {
762
+ const $xeUpload = this
763
+ const props = $xeUpload
764
+ const reactData = $xeUpload.reactData
765
+
766
+ const { fileList } = reactData
767
+ const previewImageOpts = $xeUpload.computePreviewImageOpts
768
+ const previewFn = props.previewMethod || getConfig().upload.previewMethod
769
+ const beforeDownloadFn = props.beforeDownloadMethod || getConfig().upload.beforeDownloadMethod
770
+ if (props.showPreview) {
771
+ if (previewFn) {
772
+ previewFn({
773
+ $upload: $xeUpload,
774
+ option: item
775
+ })
776
+ } else if (VxeUI.previewImage) {
777
+ VxeUI.previewImage({
778
+ ...previewImageOpts,
779
+ urlList: fileList.map(item => $xeUpload.getFileUrl(item)),
780
+ activeIndex: index,
781
+ beforeDownloadMethod: beforeDownloadFn
782
+ ? ({ index }) => {
783
+ return beforeDownloadFn({
784
+ $upload: $xeUpload,
785
+ option: fileList[index]
786
+ })
787
+ }
788
+ : undefined
789
+ })
790
+ }
791
+ }
792
+ },
793
+ handleUploadResult (item: VxeUploadDefines.FileObjItem, file: File) {
794
+ const $xeUpload = this
795
+ const props = $xeUpload
796
+ const reactData = $xeUpload.reactData
797
+
798
+ const { showErrorStatus } = props
799
+ const fileKey = $xeUpload.getFieldKey(item)
800
+ const uploadFn = props.uploadMethod || getConfig().upload.uploadMethod
801
+ if (uploadFn) {
802
+ return Promise.resolve(
803
+ uploadFn({
804
+ $upload: $xeUpload,
805
+ file,
806
+ option: item,
807
+ updateProgress (percentNum) {
808
+ const { fileCacheMaps } = reactData
809
+ const cacheItem = fileCacheMaps[$xeUpload.getFieldKey(item)]
810
+ if (cacheItem) {
811
+ cacheItem.percent = Math.max(0, Math.min(99, XEUtils.toNumber(percentNum)))
812
+ }
813
+ }
814
+ })
815
+ ).then(res => {
816
+ const { fileCacheMaps } = reactData
817
+ const cacheItem = fileCacheMaps[fileKey]
818
+ if (cacheItem) {
819
+ cacheItem.percent = 100
820
+ cacheItem.status = 'success'
821
+ }
822
+ // 处理动态字段双向绑定问题
823
+ // Object.assign(item, res)
824
+ XEUtils.each(res, (val, key) => {
825
+ $xeUpload.$set(item, key, val)
826
+ })
827
+ $xeUpload.dispatchEvent('upload-success', { option: item, data: res }, null)
828
+ }).catch((res) => {
829
+ const { fileCacheMaps } = reactData
830
+ const cacheItem = fileCacheMaps[fileKey]
831
+ if (cacheItem) {
832
+ cacheItem.status = 'error'
833
+ }
834
+ if (showErrorStatus) {
835
+ // 处理动态字段双向绑定问题
836
+ // Object.assign(item, res)
837
+ XEUtils.each(res, (val, key) => {
838
+ $xeUpload.$set(item, key, val)
839
+ })
840
+ } else {
841
+ reactData.fileList = reactData.fileList.filter(obj => $xeUpload.getFieldKey(obj) !== fileKey)
842
+ delete fileCacheMaps[fileKey]
843
+ }
844
+ $xeUpload.dispatchEvent('upload-error', { option: item, data: res }, null)
845
+ }).finally(() => {
846
+ const { fileCacheMaps } = reactData
847
+ const cacheItem = fileCacheMaps[fileKey]
848
+ if (cacheItem) {
849
+ cacheItem.loading = false
850
+ }
851
+ })
852
+ } else {
853
+ const { fileCacheMaps } = reactData
854
+ const cacheItem = fileCacheMaps[fileKey]
855
+ if (cacheItem) {
856
+ cacheItem.loading = false
857
+ }
858
+ }
859
+ return Promise.resolve()
860
+ },
861
+ handleReUpload (item: VxeUploadDefines.FileObjItem) {
862
+ const $xeUpload = this
863
+ const props = $xeUpload
864
+ const reactData = $xeUpload.reactData
865
+
866
+ const { uploadMethod, urlMode } = props
867
+ const { fileCacheMaps } = reactData
868
+ const fileKey = $xeUpload.getFieldKey(item)
869
+ const cacheItem = fileCacheMaps[fileKey]
870
+ const uploadFn = uploadMethod || getConfig().upload.uploadMethod
871
+ if (uploadFn && cacheItem) {
872
+ const file = cacheItem.file
873
+ cacheItem.loading = true
874
+ cacheItem.status = 'pending'
875
+ cacheItem.percent = 0
876
+ $xeUpload.handleUploadResult(item, file).then(() => {
877
+ if (urlMode) {
878
+ $xeUpload.handleChange(reactData.fileList)
879
+ }
880
+ })
881
+ }
882
+ },
883
+ handleUploadFile (files: File[], evnt: Event | null) {
884
+ const $xeUpload = this
885
+ const props = $xeUpload
886
+ const reactData = $xeUpload.reactData
887
+ const $xeForm = $xeUpload.$xeForm
888
+ const formItemInfo = $xeUpload.formItemInfo
889
+
890
+ const { multiple, urlMode, showLimitSize, limitSizeText, showLimitCount, limitCountText, autoSubmit } = props
891
+ const { fileList } = reactData
892
+ const beforeSelectFn = props.beforeSelectMethod || getConfig().upload.beforeSelectMethod
893
+ const uploadFn = props.uploadMethod || getConfig().upload.uploadMethod
894
+ const keyField = $xeUpload.computeKeyField
895
+ const nameProp = $xeUpload.computeNameProp
896
+ const typeProp = $xeUpload.computeTypeProp
897
+ const urlProp = $xeUpload.computeUrlProp
898
+ const sizeProp = $xeUpload.computeSizeProp
899
+ const limitMaxSize = $xeUpload.computeLimitMaxSize
900
+ const limitMaxCount = $xeUpload.computeLimitMaxCount
901
+ const limitSizeUnit = $xeUpload.computeLimitSizeUnit
902
+ let selectFiles = files
903
+
904
+ if (multiple && limitMaxCount) {
905
+ // 校验文件数量
906
+ if (showLimitCount && fileList.length >= limitMaxCount) {
907
+ if (VxeUI.modal) {
908
+ VxeUI.modal.notification({
909
+ title: getI18n('vxe.modal.errTitle'),
910
+ status: 'error',
911
+ content: limitCountText ? `${XEUtils.isFunction(limitCountText) ? limitCountText({ maxCount: limitMaxCount }) : limitCountText}` : getI18n('vxe.upload.overCountErr', [limitMaxCount])
912
+ })
913
+ }
914
+ return
915
+ }
916
+ const overNum = selectFiles.length - (limitMaxCount - fileList.length)
917
+ if (showLimitCount && overNum > 0) {
918
+ const overExtraList = selectFiles.slice(limitMaxCount - fileList.length)
919
+ if (limitCountText) {
920
+ VxeUI.modal.notification({
921
+ title: getI18n('vxe.modal.errTitle'),
922
+ status: 'error',
923
+ content: `${XEUtils.isFunction(limitCountText) ? limitCountText({ maxCount: limitMaxCount }) : limitCountText}`
924
+ })
925
+ } else if (VxeUI.modal) {
926
+ VxeUI.modal.notification({
927
+ title: getI18n('vxe.modal.errTitle'),
928
+ status: 'error',
929
+ slots: {
930
+ default (params, h) {
931
+ return h('div', {
932
+ class: 'vxe-upload--file-message-over-error'
933
+ }, [
934
+ h('div', {}, getI18n('vxe.upload.overCountExtraErr', [limitMaxCount, overNum])),
935
+ h('div', {
936
+ class: 'vxe-upload--file-message-over-extra'
937
+ }, overExtraList.map((file, index) => {
938
+ return h('div', {
939
+ key: index,
940
+ class: 'vxe-upload--file-message-over-extra-item'
941
+ }, file.name)
942
+ }))
943
+ ])
944
+ }
945
+ }
946
+ })
947
+ }
948
+ }
949
+ selectFiles = selectFiles.slice(0, limitMaxCount - fileList.length)
950
+ }
951
+
952
+ // 校验文件大小
953
+ if (showLimitSize && limitMaxSize) {
954
+ for (let i = 0; i < files.length; i++) {
955
+ const file = files[0]
956
+ if (file.size > limitMaxSize) {
957
+ if (VxeUI.modal) {
958
+ VxeUI.modal.notification({
959
+ title: getI18n('vxe.modal.errTitle'),
960
+ status: 'error',
961
+ content: limitSizeText ? `${XEUtils.isFunction(limitSizeText) ? limitSizeText({ maxSize: limitMaxSize }) : limitSizeText}` : getI18n('vxe.upload.overSizeErr', [limitSizeUnit])
962
+ })
963
+ }
964
+ return
965
+ }
966
+ }
967
+ }
968
+
969
+ const cacheMaps = Object.assign({}, reactData.fileCacheMaps)
970
+ const newFileList = multiple ? fileList : []
971
+ const uploadPromiseRests: any[] = []
972
+ selectFiles.forEach(file => {
973
+ const { name } = file
974
+ const fileKey = getUniqueKey()
975
+ const fileObj: VxeUploadDefines.FileObjItem = {
976
+ [nameProp]: name,
977
+ [typeProp]: $xeUpload.parseFileType(name),
978
+ [sizeProp]: file.size,
979
+ [urlProp]: URL.createObjectURL(file),
980
+ [keyField]: fileKey
981
+ }
982
+ if (uploadFn) {
983
+ cacheMaps[fileKey] = {
984
+ file: file,
985
+ loading: !!autoSubmit,
986
+ status: 'pending',
987
+ percent: 0
988
+ }
989
+ }
990
+ const item = fileObj
991
+ if (!beforeSelectFn || beforeSelectFn({ $upload: $xeUpload, file })) {
992
+ if (uploadFn && autoSubmit) {
993
+ uploadPromiseRests.push(
994
+ $xeUpload.handleUploadResult(item, file)
995
+ )
996
+ }
997
+ newFileList.push(item)
998
+ }
999
+ })
1000
+ reactData.fileList = newFileList
1001
+ reactData.fileCacheMaps = cacheMaps
1002
+ newFileList.forEach(item => {
1003
+ $xeUpload.dispatchEvent('add', { option: item }, evnt)
1004
+ })
1005
+ Promise.all(urlMode ? uploadPromiseRests : []).then(() => {
1006
+ const restFileList = reactData.fileList
1007
+ $xeUpload.handleChange(restFileList)
1008
+ // 自动更新校验状态
1009
+ if ($xeForm && formItemInfo) {
1010
+ $xeForm.triggerItemEvent(evnt as any, formItemInfo.itemConfig.field, restFileList)
1011
+ }
1012
+ })
1013
+ },
1014
+ handleChoose (evnt: MouseEvent | null) {
1015
+ const $xeUpload = this
1016
+ const props = $xeUpload
1017
+
1018
+ const { multiple, imageTypes, fileTypes } = props
1019
+ const isDisabled = $xeUpload.computeIsDisabled
1020
+ const isImage = $xeUpload.computeIsImage
1021
+ if (isDisabled) {
1022
+ return Promise.resolve({
1023
+ status: false,
1024
+ files: [],
1025
+ file: null
1026
+ })
1027
+ }
1028
+ return readLocalFile({
1029
+ multiple,
1030
+ types: isImage ? imageTypes : fileTypes
1031
+ }).then((params) => {
1032
+ $xeUpload.handleUploadFile(params.files, evnt)
1033
+ return params
1034
+ })
1035
+ },
1036
+ clickEvent (evnt: MouseEvent) {
1037
+ const $xeUpload = this
1038
+
1039
+ $xeUpload.handleChoose(evnt).catch(() => {
1040
+ // 错误文件类型
1041
+ })
1042
+ },
1043
+ handleRemoveEvent (evnt: MouseEvent, item: VxeUploadDefines.FileObjItem, index: number) {
1044
+ const $xeUpload = this
1045
+ const reactData = $xeUpload.reactData
1046
+ const $xeForm = $xeUpload.$xeForm
1047
+ const formItemInfo = $xeUpload.formItemInfo
1048
+
1049
+ const { fileList } = reactData
1050
+ fileList.splice(index, 1)
1051
+ $xeUpload.handleChange(fileList)
1052
+ // 自动更新校验状态
1053
+ if ($xeForm && formItemInfo) {
1054
+ $xeForm.triggerItemEvent(evnt, formItemInfo.itemConfig.field, fileList)
1055
+ }
1056
+ $xeUpload.dispatchEvent('remove', { option: item }, evnt)
1057
+ },
1058
+ removeFileEvent (evnt: MouseEvent, item: VxeUploadDefines.FileObjItem, index: number) {
1059
+ const $xeUpload = this
1060
+ const props = $xeUpload
1061
+
1062
+ const beforeRemoveFn = props.beforeRemoveMethod || getConfig().upload.beforeRemoveMethod
1063
+ const removeFn = props.removeMethod || getConfig().upload.removeMethod
1064
+ Promise.resolve(
1065
+ beforeRemoveFn
1066
+ ? beforeRemoveFn({
1067
+ $upload: $xeUpload,
1068
+ option: item
1069
+ })
1070
+ : true
1071
+ ).then(status => {
1072
+ if (status) {
1073
+ if (removeFn) {
1074
+ Promise.resolve(
1075
+ removeFn({
1076
+ $upload: $xeUpload,
1077
+ option: item
1078
+ })
1079
+ ).then(() => {
1080
+ $xeUpload.handleRemoveEvent(evnt, item, index)
1081
+ }).catch(e => e)
1082
+ } else {
1083
+ $xeUpload.handleRemoveEvent(evnt, item, index)
1084
+ }
1085
+ } else {
1086
+ $xeUpload.dispatchEvent('remove-fail', { option: item }, evnt)
1087
+ }
1088
+ })
1089
+ },
1090
+ handleDownloadEvent (evnt: MouseEvent, item: VxeUploadDefines.FileObjItem) {
1091
+ const $xeUpload = this
1092
+
1093
+ $xeUpload.dispatchEvent('download', { option: item }, evnt)
1094
+ },
1095
+ downloadFileEvent (evnt: MouseEvent, item: VxeUploadDefines.FileObjItem) {
1096
+ const $xeUpload = this
1097
+ const props = $xeUpload
1098
+
1099
+ const beforeDownloadFn = props.beforeDownloadMethod || getConfig().upload.beforeDownloadMethod
1100
+ const downloadFn = props.downloadMethod || getConfig().upload.downloadMethod
1101
+ Promise.resolve(
1102
+ beforeDownloadFn
1103
+ ? beforeDownloadFn({
1104
+ $upload: $xeUpload,
1105
+ option: item
1106
+ })
1107
+ : true
1108
+ ).then(status => {
1109
+ if (status) {
1110
+ if (downloadFn) {
1111
+ Promise.resolve(
1112
+ downloadFn({
1113
+ $upload: $xeUpload,
1114
+ option: item
1115
+ })
1116
+ ).then(() => {
1117
+ $xeUpload.handleDownloadEvent(evnt, item)
1118
+ }).catch(e => e)
1119
+ } else {
1120
+ $xeUpload.handleDownloadEvent(evnt, item)
1121
+ }
1122
+ } else {
1123
+ $xeUpload.dispatchEvent('download-fail', { option: item }, evnt)
1124
+ }
1125
+ })
1126
+ },
1127
+ handleUploadDragleaveEvent (evnt: DragEvent) {
1128
+ const $xeUpload = this
1129
+ const reactData = $xeUpload.reactData
1130
+
1131
+ const targetElem = evnt.currentTarget as HTMLDivElement
1132
+ const { clientX, clientY } = evnt
1133
+ if (targetElem) {
1134
+ const { x: targetX, y: targetY, height: targetHeight, width: targetWidth } = targetElem.getBoundingClientRect()
1135
+ if (clientX < targetX || clientX > targetX + targetWidth || clientY < targetY || clientY > targetY + targetHeight) {
1136
+ reactData.isDragUploadStatus = false
1137
+ }
1138
+ }
1139
+ },
1140
+ handleUploadDragoverEvent (evnt: DragEvent) {
1141
+ const $xeUpload = this
1142
+ const reactData = $xeUpload.reactData
1143
+
1144
+ const dataTransfer = evnt.dataTransfer
1145
+ if (dataTransfer) {
1146
+ const { items } = dataTransfer
1147
+ if (items && items.length) {
1148
+ evnt.preventDefault()
1149
+ reactData.isDragUploadStatus = true
1150
+ }
1151
+ }
1152
+ },
1153
+ uploadTransferFileEvent (evnt: Event, files: File[]) {
1154
+ const $xeUpload = this
1155
+ const props = $xeUpload
1156
+ const internalData = $xeUpload.internalData
1157
+
1158
+ const { imageTypes, fileTypes } = props
1159
+ const { imagePreviewTypes } = internalData
1160
+ const isImage = $xeUpload.computeIsImage
1161
+ if (isImage) {
1162
+ const pasteImgTypes = imagePreviewTypes.concat(imageTypes && imageTypes.length ? imageTypes : [])
1163
+ files = files.filter(file => {
1164
+ const fileType = `${file.type.split('/')[1] || ''}`.toLowerCase()
1165
+ if (pasteImgTypes.some(type => `${type}`.toLowerCase() === fileType)) {
1166
+ return true
1167
+ }
1168
+ return false
1169
+ })
1170
+ } else {
1171
+ if (fileTypes && fileTypes.length) {
1172
+ const errTypes: string[] = []
1173
+ files.forEach(file => {
1174
+ const fileType = $xeUpload.parseFileType(file.name)
1175
+ if (!fileTypes.some(type => `${type}`.toLowerCase() === fileType)) {
1176
+ errTypes.push(fileType)
1177
+ }
1178
+ })
1179
+ if (errTypes.length) {
1180
+ if (VxeUI.modal) {
1181
+ VxeUI.modal.message({
1182
+ content: getI18n('vxe.error.notType', [errTypes.join(', ')]),
1183
+ status: 'error'
1184
+ })
1185
+ }
1186
+ return
1187
+ }
1188
+ }
1189
+ }
1190
+ // 如果全部不满足条件
1191
+ if (!files.length) {
1192
+ if (VxeUI.modal) {
1193
+ VxeUI.modal.notification({
1194
+ title: getI18n('vxe.modal.errTitle'),
1195
+ status: 'error',
1196
+ content: getI18n('vxe.upload.uploadTypeErr')
1197
+ })
1198
+ }
1199
+ return
1200
+ }
1201
+ $xeUpload.handleUploadFile(files, evnt)
1202
+ },
1203
+ handleUploadDropEvent (evnt: DragEvent) {
1204
+ const $xeUpload = this
1205
+ const reactData = $xeUpload.reactData
1206
+
1207
+ const dataTransfer = evnt.dataTransfer
1208
+ if (dataTransfer) {
1209
+ const { items } = dataTransfer
1210
+ if (items && items.length) {
1211
+ evnt.preventDefault()
1212
+ const files = handleTransferFiles(items)
1213
+ if (files.length) {
1214
+ $xeUpload.uploadTransferFileEvent(evnt, files)
1215
+ }
1216
+ }
1217
+ }
1218
+ reactData.isDragUploadStatus = false
1219
+ },
1220
+ handleMoreEvent (evntParams: VxeComponentEventParams) {
1221
+ const $xeUpload = this
1222
+ const props = $xeUpload
1223
+ const slots = $xeUpload.$scopedSlots
1224
+ const reactData = $xeUpload.reactData
1225
+ const internalData = $xeUpload.internalData
1226
+
1227
+ const { xID } = $xeUpload
1228
+
1229
+ const formReadonly = $xeUpload.computeFormReadonly
1230
+ const isImage = $xeUpload.computeIsImage
1231
+
1232
+ const evnt = evntParams.$event
1233
+ if (VxeUI.modal) {
1234
+ VxeUI.modal.open({
1235
+ id: internalData.moreId,
1236
+ title: formReadonly ? getI18n('vxe.upload.morePopup.readTitle') : getI18n(`vxe.upload.morePopup.${isImage ? 'imageTitle' : 'fileTitle'}`),
1237
+ width: 660,
1238
+ height: 500,
1239
+ escClosable: true,
1240
+ showMaximize: true,
1241
+ resize: true,
1242
+ maskClosable: true,
1243
+ slots: {
1244
+ default (params, h) {
1245
+ const { showErrorStatus, dragToUpload, dragSort, dragPlaceholder } = props
1246
+ const { isActivated, isDragMove, isDragUploadStatus, dragIndex } = reactData
1247
+ const { fileList } = reactData
1248
+ const isDisabled = $xeUpload.computeIsDisabled
1249
+ const moreContSlot = slots.moreContent || slots['more-content']
1250
+
1251
+ const ons: Record<string, any> = {}
1252
+ if (dragToUpload && dragIndex === -1) {
1253
+ ons.dragover = $xeUpload.handleUploadDragoverEvent
1254
+ ons.dragleave = $xeUpload.handleUploadDragleaveEvent
1255
+ ons.drop = $xeUpload.handleUploadDropEvent
1256
+ }
1257
+
1258
+ return h('div', {
1259
+ attrs: {
1260
+ id: `refPopupElem${xID}`
1261
+ },
1262
+ class: ['vxe-upload--more-popup', {
1263
+ 'is--readonly': formReadonly,
1264
+ 'is--disabled': isDisabled,
1265
+ 'is--active': isActivated,
1266
+ 'show--error': showErrorStatus,
1267
+ 'is--drag': isDragUploadStatus
1268
+ }],
1269
+ on: ons
1270
+ }, moreContSlot
1271
+ ? getSlotVNs(moreContSlot({ options: fileList }))
1272
+ : [
1273
+ isImage
1274
+ ? (
1275
+ dragSort
1276
+ ? h('transition-group', {
1277
+ props: {
1278
+ name: `vxe-upload--drag-list${isDragMove ? '' : '-disabled'}`,
1279
+ tag: 'div'
1280
+ },
1281
+ class: 'vxe-upload--image-more-list'
1282
+ }, $xeUpload.renderImageItemList(h, fileList, true).concat($xeUpload.renderImageAction(h, true)))
1283
+ : h('div', {
1284
+ class: 'vxe-upload--image-more-list'
1285
+ }, $xeUpload.renderImageItemList(h, fileList, true).concat($xeUpload.renderImageAction(h, true)))
1286
+ )
1287
+ : h('div', {
1288
+ class: 'vxe-upload--file-more-list'
1289
+ }, [
1290
+ $xeUpload.renderFileAction(h, true),
1291
+ (
1292
+ dragSort
1293
+ ? h('transition-group', {
1294
+ props: {
1295
+ name: `vxe-upload--drag-list${isDragMove ? '' : '-disabled'}`,
1296
+ tag: 'div'
1297
+ },
1298
+ class: 'vxe-upload--file-list'
1299
+ }, $xeUpload.renderFileItemList(h, fileList, true))
1300
+ : h('div', {
1301
+ class: 'vxe-upload--file-list'
1302
+ }, $xeUpload.renderFileItemList(h, fileList, true))
1303
+ )
1304
+ ]),
1305
+ dragSort
1306
+ ? h('div', {
1307
+ attrs: {
1308
+ id: `refModalDragLineElem${xID}`
1309
+ },
1310
+ class: 'vxe-upload--drag-line'
1311
+ })
1312
+ : renderEmptyElement($xeUpload),
1313
+ isDragUploadStatus
1314
+ ? h('div', {
1315
+ class: 'vxe-upload--drag-placeholder'
1316
+ }, dragPlaceholder || getI18n('vxe.upload.dragPlaceholder'))
1317
+ : renderEmptyElement($xeUpload)
1318
+ ])
1319
+ }
1320
+ },
1321
+ events: {
1322
+ show () {
1323
+ reactData.showMorePopup = true
1324
+ },
1325
+ hide ({ $event }) {
1326
+ reactData.showMorePopup = false
1327
+ if ($event) {
1328
+ $xeUpload.dispatchEvent('more-visible', { visible: false }, $event)
1329
+ }
1330
+ }
1331
+ }
1332
+ })
1333
+ if (evnt) {
1334
+ $xeUpload.dispatchEvent('more-visible', { visible: true }, evnt)
1335
+ }
1336
+ }
1337
+ },
1338
+ // 拖拽
1339
+ handleDragSortDragstartEvent (evnt: DragEvent) {
1340
+ const $xeUpload = this
1341
+ const reactData = $xeUpload.reactData
1342
+
1343
+ evnt.stopPropagation()
1344
+ if (evnt.dataTransfer) {
1345
+ evnt.dataTransfer.setDragImage(getTpImg(), 0, 0)
1346
+ }
1347
+ const dragEl = evnt.currentTarget as HTMLElement
1348
+ const parentEl = dragEl.parentElement as HTMLDivElement
1349
+ const dragIndex = XEUtils.findIndexOf(Array.from(parentEl.children), item => dragEl === item)
1350
+ reactData.isDragMove = true
1351
+ reactData.dragIndex = dragIndex
1352
+ setTimeout(() => {
1353
+ reactData.isDragMove = false
1354
+ }, 500)
1355
+ },
1356
+ handleDragSortDragoverEvent (evnt: DragEvent) {
1357
+ const $xeUpload = this
1358
+ const reactData = $xeUpload.reactData
1359
+ const internalData = $xeUpload.internalData
1360
+
1361
+ evnt.stopPropagation()
1362
+ evnt.preventDefault()
1363
+ const { dragIndex } = reactData
1364
+ if (dragIndex === -1) {
1365
+ return
1366
+ }
1367
+ const isImage = $xeUpload.computeIsImage
1368
+ const dragEl = evnt.currentTarget as HTMLElement
1369
+ const parentEl = dragEl.parentElement as HTMLDivElement
1370
+ const currIndex = XEUtils.findIndexOf(Array.from(parentEl.children), item => dragEl === item)
1371
+ let dragPos: 'top' | 'bottom' | 'left' | 'right' | '' = ''
1372
+ if (isImage) {
1373
+ const offsetX = evnt.clientX - dragEl.getBoundingClientRect().x
1374
+ dragPos = offsetX < dragEl.clientWidth / 2 ? 'left' : 'right'
1375
+ } else {
1376
+ const offsetY = evnt.clientY - dragEl.getBoundingClientRect().y
1377
+ dragPos = offsetY < dragEl.clientHeight / 2 ? 'top' : 'bottom'
1378
+ }
1379
+ if (dragIndex === currIndex) {
1380
+ showDropTip($xeUpload, evnt, dragEl, dragPos)
1381
+ return
1382
+ }
1383
+ showDropTip($xeUpload, evnt, dragEl, dragPos)
1384
+ internalData.prevDragIndex = currIndex
1385
+ internalData.prevDragPos = dragPos
1386
+ },
1387
+ handleDragSortDragendEvent (evnt: DragEvent) {
1388
+ const $xeUpload = this
1389
+ const reactData = $xeUpload.reactData
1390
+ const internalData = $xeUpload.internalData
1391
+
1392
+ const { fileList, dragIndex } = reactData
1393
+ const { prevDragIndex, prevDragPos } = internalData
1394
+ const oldIndex = dragIndex
1395
+ const targetIndex = prevDragIndex
1396
+ const dragOffsetIndex = prevDragPos === 'bottom' || prevDragPos === 'right' ? 1 : 0
1397
+ const oldItem = fileList[oldIndex]
1398
+ const newItem = fileList[targetIndex]
1399
+ if (oldItem && newItem) {
1400
+ fileList.splice(oldIndex, 1)
1401
+ const ptfIndex = XEUtils.findIndexOf(fileList, item => newItem === item)
1402
+ const nIndex = ptfIndex + dragOffsetIndex
1403
+ fileList.splice(nIndex, 0, oldItem)
1404
+ $xeUpload.dispatchEvent('sort-dragend', {
1405
+ oldItem: oldItem,
1406
+ newItem: newItem,
1407
+ dragPos: prevDragPos as any,
1408
+ offsetIndex: dragOffsetIndex,
1409
+ _index: {
1410
+ newIndex: nIndex,
1411
+ oldIndex: oldIndex
1412
+ }
1413
+ }, evnt)
1414
+ }
1415
+ hideDropTip($xeUpload)
1416
+ reactData.dragIndex = -1
1417
+ },
1418
+ handleItemMousedownEvent (evnt: MouseEvent) {
1419
+ const $xeUpload = this
1420
+ const $xeTable = $xeUpload.$xeTable
1421
+ const reactData = $xeUpload.reactData
1422
+
1423
+ if ($xeTable) {
1424
+ evnt.stopPropagation()
1425
+ }
1426
+ reactData.isActivated = true
1427
+ },
1428
+ handleGlobalPasteEvent (evnt: ClipboardEvent) {
1429
+ const $xeUpload = this
1430
+ const props = $xeUpload
1431
+ const reactData = $xeUpload.reactData
1432
+
1433
+ const { pasteToUpload } = props
1434
+ const { isActivated } = reactData
1435
+ if (!isActivated || !pasteToUpload) {
1436
+ return
1437
+ }
1438
+ const clipboardData: DataTransfer = evnt.clipboardData || (evnt as any).originalEvent.clipboardData
1439
+ if (!clipboardData) {
1440
+ return
1441
+ }
1442
+ const { items } = clipboardData
1443
+ if (!items) {
1444
+ return
1445
+ }
1446
+ const files = handleTransferFiles(items)
1447
+ if (files.length) {
1448
+ evnt.preventDefault()
1449
+ $xeUpload.uploadTransferFileEvent(evnt, files)
1450
+ }
1451
+ },
1452
+ handleGlobalClickEvent (evnt: MouseEvent) {
1453
+ const $xeUpload = this
1454
+ const reactData = $xeUpload.reactData
1455
+
1456
+ const el = $xeUpload.$refs.refElem as HTMLDivElement
1457
+ const popupEl = $xeUpload.$refs.refPopupElem as HTMLDivElement
1458
+ let isActivated = getEventTargetNode(evnt, el).flag
1459
+ if (!isActivated && popupEl) {
1460
+ const parentEl = popupEl.parentElement || popupEl
1461
+ const modalEl = parentEl ? parentEl.parentElement : parentEl
1462
+ isActivated = getEventTargetNode(evnt, modalEl).flag
1463
+ }
1464
+ reactData.isActivated = isActivated
1465
+ },
1466
+ handleGlobalBlurEvent () {
1467
+ const $xeUpload = this
1468
+ const reactData = $xeUpload.reactData
1469
+
1470
+ reactData.isActivated = false
1471
+ },
1472
+
1473
+ //
1474
+ // Render
1475
+ //
1476
+ renderFileItemList (h: CreateElement, currList: VxeUploadDefines.FileObjItem[], isMoreView: boolean) {
1477
+ const $xeUpload = this
1478
+ const props = $xeUpload
1479
+ const slots = $xeUpload.$scopedSlots
1480
+ const reactData = $xeUpload.reactData
1481
+
1482
+ const { showRemoveButton, showDownloadButton, showProgress, progressText, showPreview, showErrorStatus, dragSort, autoSubmit, showSubmitButton } = props
1483
+ const { fileList, fileCacheMaps } = reactData
1484
+ const isDisabled = $xeUpload.computeIsDisabled
1485
+ const formReadonly = $xeUpload.computeFormReadonly
1486
+ const nameProp = $xeUpload.computeNameProp
1487
+ const typeProp = $xeUpload.computeTypeProp
1488
+ const optionSlot = slots.option
1489
+ const actionSlot = slots.action
1490
+ const cornerSlot = slots.corner
1491
+ const nameSlot = slots.name
1492
+
1493
+ const ons: Record<string, any> = {}
1494
+ if (dragSort && currList.length > 1) {
1495
+ ons.dragstart = $xeUpload.handleDragSortDragstartEvent
1496
+ ons.dragover = $xeUpload.handleDragSortDragoverEvent
1497
+ ons.dragend = $xeUpload.handleDragSortDragendEvent
1498
+ }
1499
+
1500
+ return currList.map((item, index) => {
1501
+ const fileKey = $xeUpload.getFieldKey(item)
1502
+ const cacheItem = fileCacheMaps[fileKey]
1503
+ let isLoading = false
1504
+ let isError = false
1505
+ let isPending = false
1506
+ const fileName = `${item[nameProp] || ''}`
1507
+ if (cacheItem) {
1508
+ isLoading = cacheItem.loading
1509
+ isError = cacheItem.status === 'error'
1510
+ isPending = cacheItem.status === 'pending'
1511
+ }
1512
+ return h('div', {
1513
+ key: dragSort ? fileKey : index,
1514
+ class: ['vxe-upload--file-item', {
1515
+ 'is--preview': showPreview,
1516
+ 'is--loading': isLoading,
1517
+ 'is--pending': isPending,
1518
+ 'is--error': isError
1519
+ }],
1520
+ attrs: {
1521
+ fileid: fileKey,
1522
+ draggable: dragSort ? true : null
1523
+ },
1524
+ on: ons
1525
+ }, optionSlot
1526
+ ? getSlotVNs(optionSlot({ option: item, isMoreView, options: fileList }))
1527
+ : [
1528
+ h('div', {
1529
+ class: 'vxe-upload--file-item-icon'
1530
+ }, [
1531
+ h('i', {
1532
+ class: getIcon()[`UPLOAD_FILE_TYPE_${`${item[typeProp]}`.toLocaleUpperCase() as 'DEFAULT'}`] || getIcon().UPLOAD_FILE_TYPE_DEFAULT
1533
+ })
1534
+ ]),
1535
+ h('div', {
1536
+ class: 'vxe-upload--file-item-name',
1537
+ attrs: {
1538
+ title: fileName
1539
+ },
1540
+ on: {
1541
+ click (evnt: MouseEvent) {
1542
+ if (!isLoading && !isError) {
1543
+ $xeUpload.handlePreviewFileEvent(evnt, item)
1544
+ }
1545
+ }
1546
+ }
1547
+ }, nameSlot ? getSlotVNs(nameSlot({ option: item, isMoreView, options: fileList })) : fileName),
1548
+ isLoading
1549
+ ? h('div', {
1550
+ class: 'vxe-upload--file-item-loading-icon'
1551
+ }, [
1552
+ h('i', {
1553
+ class: getIcon().UPLOAD_LOADING
1554
+ })
1555
+ ])
1556
+ : renderEmptyElement($xeUpload),
1557
+ showProgress && isLoading && cacheItem
1558
+ ? h('div', {
1559
+ class: 'vxe-upload--file-item-loading-text'
1560
+ }, progressText ? XEUtils.toFormatString(`${XEUtils.isFunction(progressText) ? progressText({}) : progressText}`, { percent: cacheItem.percent }) : getI18n('vxe.upload.uploadProgress', [cacheItem.percent]))
1561
+ : renderEmptyElement($xeUpload),
1562
+ !isLoading && ((isError && showErrorStatus) || (isPending && showSubmitButton && !autoSubmit))
1563
+ ? h('div', {
1564
+ class: 'vxe-upload--file-item-rebtn'
1565
+ }, [
1566
+ h(VxeButtonComponent, {
1567
+ props: {
1568
+ icon: isError ? getIcon().UPLOAD_IMAGE_RE_UPLOAD : getIcon().UPLOAD_IMAGE_UPLOAD,
1569
+ mode: 'text',
1570
+ status: 'primary',
1571
+ content: isError ? getI18n('vxe.upload.reUpload') : getI18n('vxe.upload.manualUpload')
1572
+ },
1573
+ on: {
1574
+ click () {
1575
+ $xeUpload.handleReUpload(item)
1576
+ }
1577
+ }
1578
+ })
1579
+ ])
1580
+ : renderEmptyElement($xeUpload),
1581
+ h('div', {
1582
+ class: 'vxe-upload--file-item-btn-wrapper'
1583
+ }, actionSlot
1584
+ ? getSlotVNs(actionSlot({ option: item, isMoreView, options: fileList, readonly: formReadonly }))
1585
+ : [
1586
+ cornerSlot
1587
+ ? h('div', {
1588
+ class: 'vxe-upload--file-item-action'
1589
+ }, getSlotVNs(cornerSlot({ option: item, isMoreView, options: fileList, readonly: formReadonly })))
1590
+ : renderEmptyElement($xeUpload),
1591
+ showDownloadButton && !isLoading
1592
+ ? h('div', {
1593
+ class: 'vxe-upload--file-item-download-btn',
1594
+ on: {
1595
+ click (evnt: MouseEvent) {
1596
+ $xeUpload.downloadFileEvent(evnt, item)
1597
+ }
1598
+ }
1599
+ }, [
1600
+ h('i', {
1601
+ class: getIcon().UPLOAD_FILE_DOWNLOAD
1602
+ })
1603
+ ])
1604
+ : renderEmptyElement($xeUpload),
1605
+ showRemoveButton && !formReadonly && !isDisabled && !isLoading
1606
+ ? h('div', {
1607
+ class: 'vxe-upload--file-item-remove-btn',
1608
+ on: {
1609
+ click (evnt: MouseEvent) {
1610
+ $xeUpload.removeFileEvent(evnt, item, index)
1611
+ }
1612
+ }
1613
+ }, [
1614
+ h('i', {
1615
+ class: getIcon().UPLOAD_FILE_REMOVE
1616
+ })
1617
+ ])
1618
+ : renderEmptyElement($xeUpload)
1619
+ ])
1620
+ ])
1621
+ })
1622
+ },
1623
+ renderFileAction (h: CreateElement, isMoreView: boolean) {
1624
+ const $xeUpload = this
1625
+ const props = $xeUpload
1626
+ const slots = $xeUpload.$scopedSlots
1627
+ const reactData = $xeUpload.reactData
1628
+
1629
+ const { showUploadButton, buttonText, buttonIcon, showButtonText, showButtonIcon, autoHiddenButton } = props
1630
+ const { fileList } = reactData
1631
+ const isDisabled = $xeUpload.computeIsDisabled
1632
+ const formReadonly = $xeUpload.computeFormReadonly
1633
+ const showTipText = $xeUpload.computedShowTipText
1634
+ const defTipText = $xeUpload.computedDefTipText
1635
+ const overCount = $xeUpload.computeOverCount
1636
+ const defaultSlot = slots.default
1637
+ const tipSlot = slots.tip || slots.hint
1638
+
1639
+ if (formReadonly || !showUploadButton) {
1640
+ return renderEmptyElement($xeUpload)
1641
+ }
1642
+ return h('div', {
1643
+ class: 'vxe-upload--file-action'
1644
+ }, [
1645
+ autoHiddenButton && overCount
1646
+ ? renderEmptyElement($xeUpload)
1647
+ : h('div', {
1648
+ class: 'vxe-upload--file-action-btn',
1649
+ on: {
1650
+ click: $xeUpload.clickEvent
1651
+ }
1652
+ }, defaultSlot
1653
+ ? getSlotVNs(defaultSlot({ isMoreView, options: fileList, $upload: $xeUpload }))
1654
+ : [
1655
+ h(VxeButtonComponent, {
1656
+ class: 'vxe-upload--file-action-button',
1657
+ props: {
1658
+ content: (isMoreView || showButtonText) ? (buttonText ? `${XEUtils.isFunction(buttonText) ? buttonText({}) : buttonText}` : getI18n('vxe.upload.fileBtnText')) : '',
1659
+ icon: showButtonIcon ? (buttonIcon || getIcon().UPLOAD_FILE_ADD) : '',
1660
+ disabled: isDisabled
1661
+ }
1662
+ })
1663
+ ]),
1664
+ showTipText && (defTipText || tipSlot)
1665
+ ? h('div', {
1666
+ class: 'vxe-upload--file-action-tip'
1667
+ }, tipSlot ? getSlotVNs(tipSlot({ isMoreView, options: fileList, $upload: $xeUpload })) : `${defTipText}`)
1668
+ : renderEmptyElement($xeUpload)
1669
+ ])
1670
+ },
1671
+ rendeFileMode (h: CreateElement) {
1672
+ const $xeUpload = this
1673
+ const props = $xeUpload
1674
+ const slots = $xeUpload.$scopedSlots
1675
+ const reactData = $xeUpload.reactData
1676
+
1677
+ const { showList, moreConfig, dragSort } = props
1678
+ const { fileList, isDragMove } = reactData
1679
+ const moreOpts = $xeUpload.computeMoreOpts
1680
+ const { maxCount, showMoreButton, layout, moreButtonText } = moreOpts
1681
+ const isHorizontal = layout === 'horizontal'
1682
+ const moreBtnSlot = slots.moreButton || slots['more-button']
1683
+
1684
+ let currList = fileList
1685
+ let overMaxNum = 0
1686
+ let isMoreMax = false
1687
+ let isMiniMore = false
1688
+ if (XEUtils.isNumber(maxCount) && fileList.length > maxCount) {
1689
+ isMoreMax = true
1690
+ isMiniMore = maxCount === 0
1691
+ overMaxNum = fileList.length - maxCount
1692
+ currList = fileList.slice(0, maxCount)
1693
+ }
1694
+
1695
+ return h('div', {
1696
+ key: 'all',
1697
+ class: 'vxe-upload--file-wrapper'
1698
+ }, showList
1699
+ ? [
1700
+ showMoreButton && moreConfig && isHorizontal
1701
+ ? renderEmptyElement($xeUpload)
1702
+ : $xeUpload.renderFileAction(h, true),
1703
+ h('div', {
1704
+ class: ['vxe-upload--file-list-wrapper', {
1705
+ 'is--horizontal': isHorizontal
1706
+ }]
1707
+ }, [
1708
+ currList.length
1709
+ ? (
1710
+ dragSort
1711
+ ? h('transition-group', {
1712
+ attrs: {
1713
+ name: `vxe-upload--drag-list${isDragMove ? '' : '-disabled'}`,
1714
+ tag: 'div'
1715
+ },
1716
+ class: 'vxe-upload--file-list'
1717
+ }, $xeUpload.renderFileItemList(h, currList, false))
1718
+ : h('div', {
1719
+ class: 'vxe-upload--file-list'
1720
+ }, $xeUpload.renderFileItemList(h, currList, false))
1721
+ )
1722
+ : renderEmptyElement($xeUpload),
1723
+ showMoreButton && overMaxNum
1724
+ ? h('div', {
1725
+ class: 'vxe-upload--file-over-more'
1726
+ }, moreBtnSlot
1727
+ ? getSlotVNs(moreBtnSlot({ options: fileList }))
1728
+ : [
1729
+ h(VxeButtonComponent, {
1730
+ props: {
1731
+ mode: 'text',
1732
+ content: moreButtonText ? (XEUtils.isFunction(moreButtonText) ? moreButtonText({ $upload: $xeUpload, options: fileList }) : XEUtils.toFormatString(moreButtonText, [fileList.length])) : getI18n(isMoreMax && isMiniMore ? 'vxe.upload.moreFileBtnText' : 'vxe.upload.moreBtnText', [fileList.length]),
1733
+ status: 'primary'
1734
+ },
1735
+ on: {
1736
+ click: $xeUpload.handleMoreEvent
1737
+ }
1738
+ })
1739
+ ])
1740
+ : renderEmptyElement($xeUpload),
1741
+ showMoreButton && moreConfig && isHorizontal
1742
+ ? $xeUpload.renderFileAction(h, false)
1743
+ : renderEmptyElement($xeUpload)
1744
+ ])
1745
+ ]
1746
+ : [
1747
+ $xeUpload.renderFileAction(h, false)
1748
+ ])
1749
+ },
1750
+ renderImageItemList (h: CreateElement, currList: VxeUploadDefines.FileObjItem[], isMoreView: boolean) {
1751
+ const $xeUpload = this
1752
+ const props = $xeUpload
1753
+ const slots = $xeUpload.$scopedSlots
1754
+ const reactData = $xeUpload.reactData
1755
+
1756
+ const { showRemoveButton, showProgress, progressText, showPreview, showErrorStatus, dragSort, autoSubmit, showSubmitButton } = props
1757
+ const { fileList, fileCacheMaps } = reactData
1758
+ const isDisabled = $xeUpload.computeIsDisabled
1759
+ const formReadonly = $xeUpload.computeFormReadonly
1760
+ const imageOpts = $xeUpload.computeImageOpts
1761
+ const imgStyle = $xeUpload.computeImgStyle
1762
+ const optionSlot = slots.option
1763
+ const actionSlot = slots.action
1764
+ const cornerSlot = slots.corner
1765
+
1766
+ const ons: Record<string, any> = {}
1767
+ if (dragSort && currList.length > 1) {
1768
+ ons.dragstart = $xeUpload.handleDragSortDragstartEvent
1769
+ ons.dragover = $xeUpload.handleDragSortDragoverEvent
1770
+ ons.dragend = $xeUpload.handleDragSortDragendEvent
1771
+ }
1772
+
1773
+ return currList.map((item, index) => {
1774
+ const fileKey = $xeUpload.getFieldKey(item)
1775
+ const cacheItem = fileCacheMaps[fileKey]
1776
+ let isLoading = false
1777
+ let isError = false
1778
+ let isPending = false
1779
+ if (cacheItem) {
1780
+ isLoading = cacheItem.loading
1781
+ isError = cacheItem.status === 'error'
1782
+ isPending = cacheItem.status === 'pending'
1783
+ }
1784
+ return h('div', {
1785
+ key: dragSort ? fileKey : index,
1786
+ class: ['vxe-upload--image-item', {
1787
+ 'is--preview': showPreview,
1788
+ 'is--circle': imageOpts.circle,
1789
+ 'is--loading': isLoading,
1790
+ 'is--pending': isPending,
1791
+ 'is--error': isError
1792
+ }],
1793
+ attrs: {
1794
+ fileid: fileKey,
1795
+ draggable: dragSort ? true : null
1796
+ },
1797
+ on: ons
1798
+ }, optionSlot
1799
+ ? getSlotVNs(optionSlot({ option: item, isMoreView, options: fileList }))
1800
+ : [
1801
+ h('div', {
1802
+ class: 'vxe-upload--image-item-box',
1803
+ style: isMoreView ? {} : imgStyle,
1804
+ on: {
1805
+ click (evnt: MouseEvent) {
1806
+ if (!isLoading && !isError) {
1807
+ $xeUpload.handlePreviewImageEvent(evnt, item, index)
1808
+ }
1809
+ }
1810
+ }
1811
+ }, [
1812
+ isLoading && cacheItem
1813
+ ? h('div', {
1814
+ class: 'vxe-upload--image-item-loading'
1815
+ }, [
1816
+ h('div', {
1817
+ class: 'vxe-upload--image-item-loading-icon'
1818
+ }, [
1819
+ h('i', {
1820
+ class: getIcon().UPLOAD_LOADING
1821
+ })
1822
+ ]),
1823
+ showProgress
1824
+ ? h('div', {
1825
+ class: 'vxe-upload--image-item-loading-text'
1826
+ }, progressText ? XEUtils.toFormatString(`${XEUtils.isFunction(progressText) ? progressText({}) : progressText}`, { percent: cacheItem.percent }) : getI18n('vxe.upload.uploadProgress', [cacheItem.percent]))
1827
+ : renderEmptyElement($xeUpload)
1828
+ ])
1829
+ : renderEmptyElement($xeUpload),
1830
+ h('div', {
1831
+ class: 'vxe-upload--image-item-img-wrapper',
1832
+ attrs: {
1833
+ title: getI18n('vxe.upload.viewItemTitle')
1834
+ }
1835
+ }, [
1836
+ h('img', {
1837
+ class: 'vxe-upload--image-item-img',
1838
+ attrs: {
1839
+ src: $xeUpload.getThumbnailFileUrl(item)
1840
+ }
1841
+ })
1842
+ ]),
1843
+ !isLoading && ((isError && showErrorStatus) || (isPending && showSubmitButton && !autoSubmit))
1844
+ ? h('div', {
1845
+ class: 'vxe-upload--image-item-rebtn'
1846
+ }, [
1847
+ h(VxeButtonComponent, {
1848
+ props: {
1849
+ icon: isError ? getIcon().UPLOAD_IMAGE_RE_UPLOAD : getIcon().UPLOAD_IMAGE_UPLOAD,
1850
+ mode: 'text',
1851
+ status: 'primary',
1852
+ content: isError ? getI18n('vxe.upload.reUpload') : getI18n('vxe.upload.manualUpload')
1853
+ },
1854
+ on: {
1855
+ click () {
1856
+ $xeUpload.handleReUpload(item)
1857
+ }
1858
+ }
1859
+ })
1860
+ ])
1861
+ : renderEmptyElement($xeUpload),
1862
+ h('div', {
1863
+ class: 'vxe-upload--image-item-btn-wrapper',
1864
+ on: {
1865
+ click (evnt: MouseEvent) {
1866
+ evnt.stopPropagation()
1867
+ }
1868
+ }
1869
+ }, actionSlot
1870
+ ? getSlotVNs(actionSlot({ option: item, isMoreView, options: fileList, readonly: formReadonly }))
1871
+ : [
1872
+ cornerSlot
1873
+ ? h('div', {
1874
+ class: 'vxe-upload--file-item-action'
1875
+ }, getSlotVNs(cornerSlot({ option: item, isMoreView, options: fileList, readonly: formReadonly })))
1876
+ : renderEmptyElement($xeUpload),
1877
+ showRemoveButton && !formReadonly && !isDisabled && !isLoading
1878
+ ? h('div', {
1879
+ class: 'vxe-upload--image-item-remove-btn',
1880
+ on: {
1881
+ click (evnt: MouseEvent) {
1882
+ evnt.stopPropagation()
1883
+ $xeUpload.removeFileEvent(evnt, item, index)
1884
+ }
1885
+ }
1886
+ }, [
1887
+ h('i', {
1888
+ class: getIcon().UPLOAD_IMAGE_REMOVE
1889
+ })
1890
+ ])
1891
+ : renderEmptyElement($xeUpload)
1892
+ ])
1893
+ ])
1894
+ ])
1895
+ })
1896
+ },
1897
+ renderImageAction (h: CreateElement, isMoreView: boolean) {
1898
+ const $xeUpload = this
1899
+ const props = $xeUpload
1900
+ const slots = $xeUpload.$scopedSlots
1901
+ const reactData = $xeUpload.reactData
1902
+
1903
+ const { showUploadButton, buttonText, buttonIcon, showButtonText, showButtonIcon, autoHiddenButton } = props
1904
+ const { fileList } = reactData
1905
+ const formReadonly = $xeUpload.computeFormReadonly
1906
+ const showTipText = $xeUpload.computedShowTipText
1907
+ const defTipText = $xeUpload.computedDefTipText
1908
+ const overCount = $xeUpload.computeOverCount
1909
+ const imgStyle = $xeUpload.computeImgStyle
1910
+ const defaultSlot = slots.default
1911
+ const tipSlot = slots.tip || slots.hint
1912
+
1913
+ if (formReadonly || !showUploadButton || (autoHiddenButton && overCount)) {
1914
+ return renderEmptyElement($xeUpload)
1915
+ }
1916
+ return h('div', {
1917
+ key: 'action',
1918
+ class: 'vxe-upload--image-action'
1919
+ }, [
1920
+ h('div', {
1921
+ class: 'vxe-upload--image-action-btn',
1922
+ on: {
1923
+ click: $xeUpload.clickEvent
1924
+ }
1925
+ }, defaultSlot
1926
+ ? defaultSlot({ isMoreView, options: fileList, $upload: $xeUpload })
1927
+ : [
1928
+ h('div', {
1929
+ class: 'vxe-upload--image-action-box',
1930
+ style: isMoreView ? {} : imgStyle
1931
+ }, [
1932
+ showButtonIcon
1933
+ ? h('div', {
1934
+ class: 'vxe-upload--image-action-icon'
1935
+ }, [
1936
+ h('i', {
1937
+ class: buttonIcon || getIcon().UPLOAD_IMAGE_ADD
1938
+ })
1939
+ ])
1940
+ : renderEmptyElement($xeUpload),
1941
+ isMoreView || showButtonText
1942
+ ? h('div', {
1943
+ class: 'vxe-upload--image-action-content'
1944
+ }, buttonText ? `${XEUtils.isFunction(buttonText) ? buttonText({}) : buttonText}` : getI18n('vxe.upload.imgBtnText'))
1945
+ : renderEmptyElement($xeUpload),
1946
+ showTipText && (defTipText || tipSlot)
1947
+ ? h('div', {
1948
+ class: 'vxe-upload--image-action-hint'
1949
+ }, tipSlot ? getSlotVNs(tipSlot({ isMoreView, options: fileList, $upload: $xeUpload })) : `${defTipText}`)
1950
+ : renderEmptyElement($xeUpload)
1951
+ ])
1952
+ ])
1953
+ ])
1954
+ },
1955
+ renderImageMode (h: CreateElement) {
1956
+ const $xeUpload = this
1957
+ const props = $xeUpload
1958
+ const slots = $xeUpload.$scopedSlots
1959
+ const reactData = $xeUpload.reactData
1960
+
1961
+ const { showList, dragSort } = props
1962
+ const { fileList, isDragMove } = reactData
1963
+ const moreOpts = $xeUpload.computeMoreOpts
1964
+ const moreBtnSlot = slots.moreButton || slots['more-button']
1965
+
1966
+ const { maxCount, showMoreButton, moreButtonText } = moreOpts
1967
+ let currList = fileList
1968
+ let overMaxNum = 0
1969
+ let isMoreMax = false
1970
+ let isMiniMore = false
1971
+ if (XEUtils.isNumber(maxCount) && fileList.length > maxCount) {
1972
+ isMoreMax = true
1973
+ isMiniMore = maxCount === 0
1974
+ overMaxNum = fileList.length - maxCount
1975
+ currList = fileList.slice(0, maxCount)
1976
+ }
1977
+
1978
+ return h('div', {
1979
+ key: 'image',
1980
+ class: 'vxe-upload--image-wrapper'
1981
+ }, showList
1982
+ ? [
1983
+ dragSort
1984
+ ? h('transition-group', {
1985
+ attrs: {
1986
+ name: `vxe-upload--drag-list${isDragMove ? '' : '-disabled'}`,
1987
+ tag: 'div'
1988
+ },
1989
+ class: 'vxe-upload--image-list'
1990
+ }, $xeUpload.renderImageItemList(h, currList, false).concat([
1991
+ showMoreButton && overMaxNum
1992
+ ? h('div', {
1993
+ key: 'om',
1994
+ class: 'vxe-upload--image-over-more'
1995
+ }, moreBtnSlot
1996
+ ? getSlotVNs(moreBtnSlot({ options: fileList }))
1997
+ : [
1998
+ h(VxeButtonComponent, {
1999
+ props: {
2000
+ mode: 'text',
2001
+ content: moreButtonText ? (XEUtils.isFunction(moreButtonText) ? moreButtonText({ $upload: $xeUpload, options: fileList }) : XEUtils.toFormatString(moreButtonText, [fileList.length])) : getI18n(isMoreMax && isMiniMore ? 'vxe.upload.moreImgBtnText' : 'vxe.upload.moreBtnText', [fileList.length]),
2002
+ status: 'primary'
2003
+ },
2004
+ on: {
2005
+ click: $xeUpload.handleMoreEvent
2006
+ }
2007
+ })
2008
+ ])
2009
+ : renderEmptyElement($xeUpload),
2010
+ $xeUpload.renderImageAction(h, false)
2011
+ ]))
2012
+ : h('div', {
2013
+ class: 'vxe-upload--image-list'
2014
+ }, $xeUpload.renderImageItemList(h, currList, false).concat([
2015
+ showMoreButton && overMaxNum
2016
+ ? h('div', {
2017
+ class: 'vxe-upload--image-over-more'
2018
+ }, moreBtnSlot
2019
+ ? getSlotVNs(moreBtnSlot({ options: fileList }))
2020
+ : [
2021
+ h(VxeButtonComponent, {
2022
+ props: {
2023
+ mode: 'text',
2024
+ content: moreButtonText ? (XEUtils.isFunction(moreButtonText) ? moreButtonText({ $upload: $xeUpload, options: fileList }) : XEUtils.toFormatString(moreButtonText, [fileList.length])) : getI18n(isMoreMax && isMiniMore ? 'vxe.upload.moreImgBtnText' : 'vxe.upload.moreBtnText', [fileList.length]),
2025
+ status: 'primary'
2026
+ },
2027
+ on: {
2028
+ click: $xeUpload.handleMoreEvent
2029
+ }
2030
+ })
2031
+ ])
2032
+ : renderEmptyElement($xeUpload),
2033
+ $xeUpload.renderImageAction(h, false)
2034
+ ]))
2035
+ ]
2036
+ : [
2037
+ h('div', {
2038
+ class: 'vxe-upload--image-list'
2039
+ }, [
2040
+ $xeUpload.renderImageAction(h, false)
2041
+ ])
2042
+ ])
2043
+ },
2044
+ renderVN (h: CreateElement): VNode {
2045
+ const $xeUpload = this
2046
+ const props = $xeUpload
2047
+ const reactData = $xeUpload.reactData
2048
+
2049
+ const { showErrorStatus, dragToUpload, pasteToUpload, dragSort, dragPlaceholder } = props
2050
+ const { isDragUploadStatus, showMorePopup, isActivated, dragIndex } = reactData
2051
+ const vSize = $xeUpload.computeSize
2052
+ const isDisabled = $xeUpload.computeIsDisabled
2053
+ const formReadonly = $xeUpload.computeFormReadonly
2054
+ const isImage = $xeUpload.computeIsImage
2055
+
2056
+ const ons: Record<string, any> = {}
2057
+ if (dragToUpload && dragIndex === -1) {
2058
+ ons.dragover = $xeUpload.handleUploadDragoverEvent
2059
+ ons.dragleave = $xeUpload.handleUploadDragleaveEvent
2060
+ ons.drop = $xeUpload.handleUploadDropEvent
2061
+ }
2062
+
2063
+ return h('div', {
2064
+ ref: 'refElem',
2065
+ class: ['vxe-upload', {
2066
+ [`size--${vSize}`]: vSize,
2067
+ 'is--active': isActivated,
2068
+ 'is--readonly': formReadonly,
2069
+ 'is--disabled': isDisabled,
2070
+ 'is--paste': pasteToUpload,
2071
+ 'show--error': showErrorStatus,
2072
+ 'is--drag': isDragUploadStatus
2073
+ }],
2074
+ on: ons
2075
+ }, [
2076
+ isImage ? $xeUpload.renderImageMode(h) : $xeUpload.rendeFileMode(h),
2077
+ dragSort
2078
+ ? h('div', {
2079
+ ref: 'refDragLineElem',
2080
+ class: 'vxe-upload--drag-line'
2081
+ })
2082
+ : renderEmptyElement($xeUpload),
2083
+ isDragUploadStatus && !showMorePopup
2084
+ ? h('div', {
2085
+ class: 'vxe-upload--drag-placeholder'
2086
+ }, dragPlaceholder || getI18n('vxe.upload.dragPlaceholder'))
2087
+ : renderEmptyElement($xeUpload)
2088
+ ])
2089
+ }
2090
+ },
2091
+ created () {
2092
+ const $xeUpload = this
2093
+
2094
+ $xeUpload.updateFileList()
2095
+ },
2096
+ mounted () {
2097
+ const $xeUpload = this
2098
+ const props = $xeUpload
2099
+
2100
+ if (props.multiple && props.singleMode) {
2101
+ errLog('vxe.error.errConflicts', ['[upload] multiple', 'single-mode'])
2102
+ }
2103
+ if (props.imageStyle) {
2104
+ warnLog('vxe.error.delProp', ['[upload] image-style', 'image-config'])
2105
+ }
2106
+
2107
+ if (props.dragSort) {
2108
+ initTpImg()
2109
+ }
2110
+ globalEvents.on($xeUpload, 'paste', $xeUpload.handleGlobalPasteEvent)
2111
+ globalEvents.on($xeUpload, 'click', $xeUpload.handleGlobalClickEvent)
2112
+ globalEvents.on($xeUpload, 'blur', $xeUpload.handleGlobalBlurEvent)
2113
+ },
2114
+ beforeDestroy () {
2115
+ const $xeUpload = this
2116
+ const reactData = $xeUpload.reactData
2117
+ const internalData = $xeUpload.internalData
2118
+
2119
+ reactData.isDragUploadStatus = false
2120
+ globalEvents.off($xeUpload, 'paste')
2121
+ globalEvents.off($xeUpload, 'click')
2122
+ globalEvents.off($xeUpload, 'blur')
2123
+ XEUtils.assign(reactData, createReactData())
2124
+ XEUtils.assign(internalData, createInternalData())
2125
+ },
2126
+ render (this: any, h) {
2127
+ return this.renderVN(h)
2128
+ }
2129
+ }) /* define-vxe-component end */