vxe-pc-ui 3.13.11 → 3.13.13

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