misp-ui-library-test 0.0.1

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 (373) hide show
  1. package/README.md +113 -0
  2. package/dist/theme-chalk/alert/index.scss +152 -0
  3. package/dist/theme-chalk/avatar/index.scss +51 -0
  4. package/dist/theme-chalk/backtop/index.scss +38 -0
  5. package/dist/theme-chalk/badge/index.scss +63 -0
  6. package/dist/theme-chalk/breadcrumb/index.scss +36 -0
  7. package/dist/theme-chalk/breadcrumb-item/index.scss +36 -0
  8. package/dist/theme-chalk/button/index.scss +157 -0
  9. package/dist/theme-chalk/card/index.scss +38 -0
  10. package/dist/theme-chalk/chart/index.scss +21 -0
  11. package/dist/theme-chalk/checkbox/index.scss +358 -0
  12. package/dist/theme-chalk/col/index.scss +131 -0
  13. package/dist/theme-chalk/container/index.scss +40 -0
  14. package/dist/theme-chalk/css/alert.css +484 -0
  15. package/dist/theme-chalk/css/avatar.css +409 -0
  16. package/dist/theme-chalk/css/backtop.css +401 -0
  17. package/dist/theme-chalk/css/badge.css +419 -0
  18. package/dist/theme-chalk/css/breadcrumb-item.css +395 -0
  19. package/dist/theme-chalk/css/breadcrumb.css +395 -0
  20. package/dist/theme-chalk/css/button.css +587 -0
  21. package/dist/theme-chalk/css/card.css +397 -0
  22. package/dist/theme-chalk/css/chart.css +386 -0
  23. package/dist/theme-chalk/css/checkbox.css +648 -0
  24. package/dist/theme-chalk/css/col.css +2111 -0
  25. package/dist/theme-chalk/css/container.css +404 -0
  26. package/dist/theme-chalk/css/dialog.css +505 -0
  27. package/dist/theme-chalk/css/divider.css +405 -0
  28. package/dist/theme-chalk/css/drawer.css +546 -0
  29. package/dist/theme-chalk/css/empty.css +394 -0
  30. package/dist/theme-chalk/css/form.css +561 -0
  31. package/dist/theme-chalk/css/icon.css +1534 -0
  32. package/dist/theme-chalk/css/image.css +400 -0
  33. package/dist/theme-chalk/css/input-number.css +424 -0
  34. package/dist/theme-chalk/css/input.css +721 -0
  35. package/dist/theme-chalk/css/link.css +424 -0
  36. package/dist/theme-chalk/css/loading.css +483 -0
  37. package/dist/theme-chalk/css/message-box.css +479 -0
  38. package/dist/theme-chalk/css/message.css +456 -0
  39. package/dist/theme-chalk/css/no-data.css +397 -0
  40. package/dist/theme-chalk/css/notification.css +431 -0
  41. package/dist/theme-chalk/css/page-header.css +396 -0
  42. package/dist/theme-chalk/css/pagination.css +565 -0
  43. package/dist/theme-chalk/css/popover.css +421 -0
  44. package/dist/theme-chalk/css/popper.css +454 -0
  45. package/dist/theme-chalk/css/progress.css +451 -0
  46. package/dist/theme-chalk/css/radio.css +626 -0
  47. package/dist/theme-chalk/css/rate.css +414 -0
  48. package/dist/theme-chalk/css/result.css +403 -0
  49. package/dist/theme-chalk/css/row.css +433 -0
  50. package/dist/theme-chalk/css/scrollbar.css +422 -0
  51. package/dist/theme-chalk/css/select.css +1897 -0
  52. package/dist/theme-chalk/css/skeleton-item.css +407 -0
  53. package/dist/theme-chalk/css/skeleton.css +390 -0
  54. package/dist/theme-chalk/css/slider.css +460 -0
  55. package/dist/theme-chalk/css/spinner.css +403 -0
  56. package/dist/theme-chalk/css/statistic.css +396 -0
  57. package/dist/theme-chalk/css/status-timeline-chart.css +388 -0
  58. package/dist/theme-chalk/css/step.css +496 -0
  59. package/dist/theme-chalk/css/steps.css +496 -0
  60. package/dist/theme-chalk/css/switch.css +507 -0
  61. package/dist/theme-chalk/css/tab-pane.css +457 -0
  62. package/dist/theme-chalk/css/table.css +461 -0
  63. package/dist/theme-chalk/css/tabs-navigation.css +925 -0
  64. package/dist/theme-chalk/css/tabs.css +457 -0
  65. package/dist/theme-chalk/css/tag.css +599 -0
  66. package/dist/theme-chalk/css/time-picker.css +683 -0
  67. package/dist/theme-chalk/css/timeline-item.css +459 -0
  68. package/dist/theme-chalk/css/timeline.css +459 -0
  69. package/dist/theme-chalk/css/tooltip.css +485 -0
  70. package/dist/theme-chalk/css/tree.css +473 -0
  71. package/dist/theme-chalk/css/upload.css +665 -0
  72. package/dist/theme-chalk/dialog/index.scss +168 -0
  73. package/dist/theme-chalk/divider/index.scss +46 -0
  74. package/dist/theme-chalk/drawer/index.scss +172 -0
  75. package/dist/theme-chalk/empty/index.scss +36 -0
  76. package/dist/theme-chalk/fonts/element-icons.ttf +0 -0
  77. package/dist/theme-chalk/fonts/element-icons.woff +0 -0
  78. package/dist/theme-chalk/form/index.scss +220 -0
  79. package/dist/theme-chalk/icon/index.scss +1171 -0
  80. package/dist/theme-chalk/image/index.scss +39 -0
  81. package/dist/theme-chalk/index.scss +127 -0
  82. package/dist/theme-chalk/input/index.scss +363 -0
  83. package/dist/theme-chalk/input-number/index.scss +71 -0
  84. package/dist/theme-chalk/link/index.scss +75 -0
  85. package/dist/theme-chalk/loading/index.scss +131 -0
  86. package/dist/theme-chalk/message/index.scss +100 -0
  87. package/dist/theme-chalk/message-box/index.scss +131 -0
  88. package/dist/theme-chalk/mixins.scss +203 -0
  89. package/dist/theme-chalk/no-data/index.scss +36 -0
  90. package/dist/theme-chalk/notification/index.scss +76 -0
  91. package/dist/theme-chalk/page-header/index.scss +36 -0
  92. package/dist/theme-chalk/pagination/index.scss +225 -0
  93. package/dist/theme-chalk/popover/index.scss +56 -0
  94. package/dist/theme-chalk/popper/index.scss +89 -0
  95. package/dist/theme-chalk/progress/index.scss +105 -0
  96. package/dist/theme-chalk/radio/index.scss +328 -0
  97. package/dist/theme-chalk/rate/index.scss +56 -0
  98. package/dist/theme-chalk/reset.scss +262 -0
  99. package/dist/theme-chalk/result/index.scss +46 -0
  100. package/dist/theme-chalk/row/index.scss +88 -0
  101. package/dist/theme-chalk/scrollbar/index.scss +67 -0
  102. package/dist/theme-chalk/select/index.scss +223 -0
  103. package/dist/theme-chalk/skeleton/index.scss +30 -0
  104. package/dist/theme-chalk/skeleton-item/index.scss +49 -0
  105. package/dist/theme-chalk/slider/index.scss +113 -0
  106. package/dist/theme-chalk/spinner/index.scss +40 -0
  107. package/dist/theme-chalk/statistic/index.scss +38 -0
  108. package/dist/theme-chalk/status-timeline-chart/index.scss +23 -0
  109. package/dist/theme-chalk/step/index.scss +160 -0
  110. package/dist/theme-chalk/steps/index.scss +160 -0
  111. package/dist/theme-chalk/switch/index.scss +153 -0
  112. package/dist/theme-chalk/tab-pane/index.scss +112 -0
  113. package/dist/theme-chalk/table/index.scss +110 -0
  114. package/dist/theme-chalk/tabs/index.scss +112 -0
  115. package/dist/theme-chalk/tabs-navigation/index.scss +631 -0
  116. package/dist/theme-chalk/tag/index.scss +138 -0
  117. package/dist/theme-chalk/themes/blue.scss +76 -0
  118. package/dist/theme-chalk/themes/dark.scss +99 -0
  119. package/dist/theme-chalk/themes/index.scss +260 -0
  120. package/dist/theme-chalk/themes/light.scss +99 -0
  121. package/dist/theme-chalk/time-picker/index.scss +332 -0
  122. package/dist/theme-chalk/timeline/index.scss +119 -0
  123. package/dist/theme-chalk/timeline-item/index.scss +119 -0
  124. package/dist/theme-chalk/tooltip/index.scss +122 -0
  125. package/dist/theme-chalk/tree/index.scss +125 -0
  126. package/dist/theme-chalk/upload/index.scss +348 -0
  127. package/dist/theme-chalk/variables.scss +93 -0
  128. package/dist/vue2-ui-library.cjs.temp.js.map +1 -0
  129. package/dist/vue2-ui-library.common.js +28 -0
  130. package/dist/vue2-ui-library.common.js.map +1 -0
  131. package/dist/vue2-ui-library.esm.js +29 -0
  132. package/dist/vue2-ui-library.umd.js +27 -0
  133. package/package.json +161 -0
  134. package/src/directives/clickoutside/index.js +111 -0
  135. package/src/directives/init/index.js +50 -0
  136. package/src/directives/resize/index.js +69 -0
  137. package/src/index.js +174 -0
  138. package/src/mixins/emitter.js +47 -0
  139. package/src/mixins/focus.js +42 -0
  140. package/src/mixins/locale.js +24 -0
  141. package/src/mixins/migrating.js +46 -0
  142. package/src/packages/alert/index.js +12 -0
  143. package/src/packages/alert/src/main.vue +98 -0
  144. package/src/packages/aside/index.js +12 -0
  145. package/src/packages/aside/src/main.vue +20 -0
  146. package/src/packages/auto-grid-layout/index.js +18 -0
  147. package/src/packages/auto-grid-layout/prop.js +92 -0
  148. package/src/packages/auto-grid-layout/src/components/GridItem.vue +759 -0
  149. package/src/packages/auto-grid-layout/src/components/GridLayout.vue +367 -0
  150. package/src/packages/auto-grid-layout/src/main.vue +287 -0
  151. package/src/packages/auto-grid-layout/src/utils/DOM.js +46 -0
  152. package/src/packages/auto-grid-layout/src/utils/interact.js +333 -0
  153. package/src/packages/auto-grid-layout/src/utils/responsiveUtils.js +75 -0
  154. package/src/packages/auto-grid-layout/src/utils/utils.js +339 -0
  155. package/src/packages/autocomplete/index.js +12 -0
  156. package/src/packages/autocomplete/src/main.vue +170 -0
  157. package/src/packages/avatar/index.js +12 -0
  158. package/src/packages/avatar/src/main.vue +87 -0
  159. package/src/packages/backtop/index.js +12 -0
  160. package/src/packages/backtop/src/main.vue +120 -0
  161. package/src/packages/badge/index.js +12 -0
  162. package/src/packages/badge/src/main.vue +53 -0
  163. package/src/packages/breadcrumb/index.js +12 -0
  164. package/src/packages/breadcrumb/src/main.vue +34 -0
  165. package/src/packages/breadcrumb-item/index.js +12 -0
  166. package/src/packages/breadcrumb-item/src/main.vue +41 -0
  167. package/src/packages/button/index.js +13 -0
  168. package/src/packages/button/src/main.vue +106 -0
  169. package/src/packages/calendar/index.js +12 -0
  170. package/src/packages/calendar/src/main.vue +173 -0
  171. package/src/packages/card/index.js +12 -0
  172. package/src/packages/card/src/main.vue +26 -0
  173. package/src/packages/carousel/index.js +12 -0
  174. package/src/packages/carousel/src/main.vue +186 -0
  175. package/src/packages/carousel-item/index.js +12 -0
  176. package/src/packages/carousel-item/src/main.vue +34 -0
  177. package/src/packages/cascader/index.js +12 -0
  178. package/src/packages/cascader/src/main.vue +232 -0
  179. package/src/packages/chart/index.js +7 -0
  180. package/src/packages/chart/src/axis-chart.js +700 -0
  181. package/src/packages/chart/src/main.vue +828 -0
  182. package/src/packages/chart/src/utils.js +21 -0
  183. package/src/packages/checkbox/index.js +44 -0
  184. package/src/packages/checkbox/src/main.vue +312 -0
  185. package/src/packages/col/index.js +12 -0
  186. package/src/packages/col/src/main.vue +85 -0
  187. package/src/packages/collapse/index.js +12 -0
  188. package/src/packages/collapse/src/main.vue +69 -0
  189. package/src/packages/collapse-item/index.js +12 -0
  190. package/src/packages/collapse-item/src/main.vue +75 -0
  191. package/src/packages/color-picker/index.js +12 -0
  192. package/src/packages/color-picker/src/main.vue +206 -0
  193. package/src/packages/container/index.js +12 -0
  194. package/src/packages/container/src/main.vue +33 -0
  195. package/src/packages/date-picker/index.js +12 -0
  196. package/src/packages/date-picker/src/main.vue +246 -0
  197. package/src/packages/descriptions/index.js +12 -0
  198. package/src/packages/descriptions/src/main.vue +89 -0
  199. package/src/packages/descriptions-item/index.js +12 -0
  200. package/src/packages/descriptions-item/src/main.vue +26 -0
  201. package/src/packages/dialog/index.js +12 -0
  202. package/src/packages/dialog/src/main.vue +336 -0
  203. package/src/packages/divider/index.js +12 -0
  204. package/src/packages/divider/src/main.vue +37 -0
  205. package/src/packages/drawer/index.js +7 -0
  206. package/src/packages/drawer/src/main.vue +310 -0
  207. package/src/packages/dropdown/index.js +12 -0
  208. package/src/packages/dropdown/src/main.vue +82 -0
  209. package/src/packages/dropdown-menu-item/index.js +12 -0
  210. package/src/packages/dropdown-menu-item/src/main.vue +29 -0
  211. package/src/packages/empty/index.js +12 -0
  212. package/src/packages/empty/src/img-empty.vue +12 -0
  213. package/src/packages/empty/src/main.vue +49 -0
  214. package/src/packages/footer/index.js +12 -0
  215. package/src/packages/footer/src/main.vue +20 -0
  216. package/src/packages/form/index.js +13 -0
  217. package/src/packages/form/src/form-field.vue +790 -0
  218. package/src/packages/form/src/form-item.vue +464 -0
  219. package/src/packages/form/src/label-wrap.vue +127 -0
  220. package/src/packages/form/src/main.vue +442 -0
  221. package/src/packages/form-item/index.js +11 -0
  222. package/src/packages/header/index.js +12 -0
  223. package/src/packages/header/src/main.vue +20 -0
  224. package/src/packages/icon/index.js +12 -0
  225. package/src/packages/icon/src/main.vue +48 -0
  226. package/src/packages/image/index.js +12 -0
  227. package/src/packages/image/src/main.vue +224 -0
  228. package/src/packages/input/index.js +13 -0
  229. package/src/packages/input/src/calcTextareaHeight.js +123 -0
  230. package/src/packages/input/src/main.vue +510 -0
  231. package/src/packages/input-number/index.js +12 -0
  232. package/src/packages/input-number/src/main.vue +121 -0
  233. package/src/packages/link/index.js +12 -0
  234. package/src/packages/link/src/main.vue +53 -0
  235. package/src/packages/loading/index.js +17 -0
  236. package/src/packages/loading/src/directive.js +54 -0
  237. package/src/packages/loading/src/main.vue +38 -0
  238. package/src/packages/loading/src/service.js +63 -0
  239. package/src/packages/main/index.js +12 -0
  240. package/src/packages/main/src/main.vue +12 -0
  241. package/src/packages/menu/index.js +12 -0
  242. package/src/packages/menu/src/main.vue +117 -0
  243. package/src/packages/menu-item/index.js +12 -0
  244. package/src/packages/menu-item/src/main.vue +61 -0
  245. package/src/packages/message/index.js +95 -0
  246. package/src/packages/message/src/main.vue +131 -0
  247. package/src/packages/message-box/index.js +75 -0
  248. package/src/packages/message-box/src/main.vue +207 -0
  249. package/src/packages/no-data/index.js +8 -0
  250. package/src/packages/no-data/src/main.vue +23 -0
  251. package/src/packages/notification/index.js +72 -0
  252. package/src/packages/notification/src/main.vue +139 -0
  253. package/src/packages/option/index.js +13 -0
  254. package/src/packages/page-header/index.js +12 -0
  255. package/src/packages/page-header/src/main.vue +27 -0
  256. package/src/packages/pagination/index.js +12 -0
  257. package/src/packages/pagination/src/main.vue +255 -0
  258. package/src/packages/popconfirm/index.js +12 -0
  259. package/src/packages/popconfirm/src/main.vue +89 -0
  260. package/src/packages/popover/index.js +12 -0
  261. package/src/packages/popover/src/main.vue +452 -0
  262. package/src/packages/progress/index.js +12 -0
  263. package/src/packages/progress/src/main.vue +236 -0
  264. package/src/packages/radio/index.js +44 -0
  265. package/src/packages/radio/src/main.vue +291 -0
  266. package/src/packages/rate/index.js +12 -0
  267. package/src/packages/rate/src/main.vue +129 -0
  268. package/src/packages/result/index.js +12 -0
  269. package/src/packages/result/src/main.vue +52 -0
  270. package/src/packages/row/index.js +12 -0
  271. package/src/packages/row/src/main.vue +57 -0
  272. package/src/packages/scrollbar/index.js +12 -0
  273. package/src/packages/scrollbar/src/bar.vue +116 -0
  274. package/src/packages/scrollbar/src/main.vue +124 -0
  275. package/src/packages/select/index.js +15 -0
  276. package/src/packages/select/src/clickoutside.js +20 -0
  277. package/src/packages/select/src/main.vue +1055 -0
  278. package/src/packages/select/src/navigation-mixin.js +49 -0
  279. package/src/packages/select/src/option.vue +249 -0
  280. package/src/packages/select/src/select-dropdown.vue +95 -0
  281. package/src/packages/select/src/utils.js +5 -0
  282. package/src/packages/skeleton/index.js +12 -0
  283. package/src/packages/skeleton/src/main.vue +76 -0
  284. package/src/packages/skeleton-item/index.js +12 -0
  285. package/src/packages/skeleton-item/src/img-placeholder.vue +13 -0
  286. package/src/packages/skeleton-item/src/main.vue +22 -0
  287. package/src/packages/slider/index.js +12 -0
  288. package/src/packages/slider/src/main.vue +176 -0
  289. package/src/packages/spinner/index.js +12 -0
  290. package/src/packages/spinner/src/main.vue +27 -0
  291. package/src/packages/statistic/index.js +12 -0
  292. package/src/packages/statistic/src/main.vue +100 -0
  293. package/src/packages/status-timeline-chart/index.js +7 -0
  294. package/src/packages/status-timeline-chart/src/constants.js +20 -0
  295. package/src/packages/status-timeline-chart/src/main.vue +499 -0
  296. package/src/packages/status-timeline-chart/src/option-builder.js +475 -0
  297. package/src/packages/step/index.js +12 -0
  298. package/src/packages/step/src/main.vue +183 -0
  299. package/src/packages/steps/index.js +12 -0
  300. package/src/packages/steps/src/main.vue +57 -0
  301. package/src/packages/submenu/index.js +12 -0
  302. package/src/packages/submenu/src/main.vue +68 -0
  303. package/src/packages/switch/index.js +12 -0
  304. package/src/packages/switch/src/main.vue +166 -0
  305. package/src/packages/tab-pane/index.js +12 -0
  306. package/src/packages/tab-pane/src/main.vue +74 -0
  307. package/src/packages/table/index.js +8 -0
  308. package/src/packages/table/src/components/PagePagination.vue +82 -0
  309. package/src/packages/table/src/main.vue +153 -0
  310. package/src/packages/tabs/index.js +12 -0
  311. package/src/packages/tabs/src/main.vue +167 -0
  312. package/src/packages/tabs-navigation/index.js +7 -0
  313. package/src/packages/tabs-navigation/src/main.vue +462 -0
  314. package/src/packages/tag/index.js +12 -0
  315. package/src/packages/tag/src/main.vue +194 -0
  316. package/src/packages/time-picker/index.js +17 -0
  317. package/src/packages/time-picker/src/date-utils.js +455 -0
  318. package/src/packages/time-picker/src/main.vue +321 -0
  319. package/src/packages/time-picker/src/pane/date-range.vue +193 -0
  320. package/src/packages/time-picker/src/pane/date-time-range.vue +362 -0
  321. package/src/packages/time-picker/src/pane/date-time.vue +362 -0
  322. package/src/packages/time-picker/src/pane/date.vue +441 -0
  323. package/src/packages/time-picker/src/pane/time.vue +260 -0
  324. package/src/packages/time-picker/src/time-input.vue +203 -0
  325. package/src/packages/time-picker/src/time-range-input.vue +170 -0
  326. package/src/packages/timeline/index.js +12 -0
  327. package/src/packages/timeline/src/main.vue +24 -0
  328. package/src/packages/timeline-item/index.js +12 -0
  329. package/src/packages/timeline-item/src/main.vue +78 -0
  330. package/src/packages/tooltip/index.js +12 -0
  331. package/src/packages/tooltip/src/main.js +367 -0
  332. package/src/packages/transfer/index.js +8 -0
  333. package/src/packages/transfer/src/main.vue +229 -0
  334. package/src/packages/transfer/src/transfer-panel.vue +245 -0
  335. package/src/packages/transitions/collapse-transition.js +75 -0
  336. package/src/packages/tree/index.js +12 -0
  337. package/src/packages/tree/src/main.vue +322 -0
  338. package/src/packages/tree/src/model/node.js +348 -0
  339. package/src/packages/tree/src/model/tree-store.js +354 -0
  340. package/src/packages/tree/src/model/util.js +10 -0
  341. package/src/packages/tree/src/tree-node.vue +262 -0
  342. package/src/packages/upload/index.js +9 -0
  343. package/src/packages/upload/src/main.vue +415 -0
  344. package/src/playground/mixins/element.js +98 -0
  345. package/src/playground/types/element.js +197 -0
  346. package/src/playground/types/layout.js +80 -0
  347. package/src/plugins/i18n.js +125 -0
  348. package/src/styles/fonts/element-icons.ttf +0 -0
  349. package/src/styles/fonts/element-icons.woff +0 -0
  350. package/src/styles/index.scss +138 -0
  351. package/src/styles/reset.scss +257 -0
  352. package/src/styles/themes/blue.scss +75 -0
  353. package/src/styles/themes/dark.scss +98 -0
  354. package/src/styles/themes/index.scss +34 -0
  355. package/src/styles/themes/light.scss +98 -0
  356. package/src/styles/themes/variables.scss +233 -0
  357. package/src/styles/variables.scss +146 -0
  358. package/src/utils/async-validator/index.js +659 -0
  359. package/src/utils/browser/index.js +39 -0
  360. package/src/utils/color.js +76 -0
  361. package/src/utils/dom/index.js +421 -0
  362. package/src/utils/dom/scrollbar-width.js +49 -0
  363. package/src/utils/draggable/core.js +379 -0
  364. package/src/utils/draggable/draggable.js +478 -0
  365. package/src/utils/draggable/index.js +61 -0
  366. package/src/utils/draggable/sortable.js +751 -0
  367. package/src/utils/lodash/index.js +2395 -0
  368. package/src/utils/moment/index.js +909 -0
  369. package/src/utils/playground/index.js +37 -0
  370. package/src/utils/popper/index.js +308 -0
  371. package/src/utils/popper/popper.js +1132 -0
  372. package/src/utils/popper/popup-manager.js +288 -0
  373. package/src/utils/popper/popup.js +344 -0
@@ -0,0 +1,659 @@
1
+ /**
2
+ * 默认校验错误消息模板
3
+ */
4
+ const defaultMessages = {
5
+ default: '字段 %s 校验失败',
6
+ required: '%s 是必填项',
7
+ enum: '%s 必须是以下值之一: %s',
8
+ whitespace: '%s 不能为空',
9
+ date: {
10
+ format: '%s 日期 %s 不符合格式 %s',
11
+ parse: '%s 日期无法解析',
12
+ invalid: '%s 日期 %s 无效',
13
+ },
14
+ types: {
15
+ string: '%s 不是字符串类型',
16
+ method: '%s 不是函数类型',
17
+ array: '%s 不是数组类型',
18
+ object: '%s 不是对象类型',
19
+ number: '%s 不是数字类型',
20
+ date: '%s 不是日期类型',
21
+ boolean: '%s 不是布尔类型',
22
+ integer: '%s 不是整数类型',
23
+ float: '%s 不是浮点数类型',
24
+ url: '%s 不是有效的 URL',
25
+ hex: '%s 不是有效的十六进制颜色',
26
+ email: '%s 不是有效的邮箱地址',
27
+ regexp: '%s 不是有效的正则表达式',
28
+ },
29
+ string: {
30
+ len: '%s 必须正好是 %s 个字符',
31
+ min: '%s 长度不能少于 %s 个字符',
32
+ max: '%s 长度不能超过 %s 个字符',
33
+ range: '%s 长度必须在 %s 到 %s 个字符之间',
34
+ },
35
+ number: {
36
+ len: '%s 必须等于 %s',
37
+ min: '%s 不能小于 %s',
38
+ max: '%s 不能大于 %s',
39
+ range: '%s 必须在 %s 到 %s 之间',
40
+ },
41
+ array: {
42
+ len: '%s 长度必须正好是 %s',
43
+ min: '%s 长度不能少于 %s',
44
+ max: '%s 长度不能超过 %s',
45
+ range: '%s 长度必须在 %s 到 %s 之间',
46
+ },
47
+ pattern: {
48
+ mismatch: '%s 的值 %s 不匹配模式 %s',
49
+ },
50
+ }
51
+
52
+ /**
53
+ * 内置正则表达式模式
54
+ */
55
+ const pattern = {
56
+ email: /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9\u007F-\uFFFF]+\.)+[a-zA-Z\u007F-\uFFFF]{2,}))$/,
57
+ url: /^(?!mailto:)(?:(?:https?|ftp):\/\/|\/\/)(?:\S+(?::\S*)?@)?(?:(?:(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[0-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u007f-\uffff0-9]+-?)*[a-z\u007f-\uffff0-9]+)(?:\.(?:[a-z\u007f-\uffff0-9]+-?)*[a-z\u007f-\uffff0-9]+)*(?:\.(?:[a-z\u007f-\uffff]{2,})))|localhost)(?::\d{2,5})?(?:\/[^\s]*)?$/i,
58
+ hex: /^#?([a-f0-9]{6}|[a-f0-9]{3})$/i,
59
+ date: /^\d{4}-\d{2}-\d{2}( \d{2}:\d{2}:\d{2}(.\d+)?)?$/,
60
+ dateObject: Date,
61
+ digit: /^\d+$/,
62
+ number: /^-?\d*(\.\d+)?$/,
63
+ integer: /^-?\d+$/,
64
+ ipv4: /^(\d{1,2}|1\d\d|2[0-4]\d|25[0-4])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-4])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-4])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-4])$/,
65
+ ipv6: /^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))$/,
66
+ }
67
+
68
+ /**
69
+ * 判断值是否为空
70
+ * @param {*} value - 待检查的值
71
+ * @returns {boolean} 如果值为 undefined, null, 空字符串或空数组则返回 true
72
+ */
73
+ function isEmptyValue(value) {
74
+ if (value === undefined || value === null) {
75
+ return true
76
+ }
77
+ if (typeof value === 'string' && value.trim() === '') {
78
+ return true
79
+ }
80
+ if (Array.isArray(value) && value.length === 0) {
81
+ return true
82
+ }
83
+ return false
84
+ }
85
+
86
+ /**
87
+ * 格式化字符串模板,替换 %s占位符
88
+ * @param {string} template - 包含 %s 占位模板字符串
89
+ * @param {...*} args - 用于替换占位符的参数
90
+ * @returns {string} 格式化后的字符串
91
+ */
92
+ function format(template, ...args) {
93
+ let result = template
94
+ for (let i = 0; i < args.length; i++) {
95
+ result = result.replace('%s', args[i])
96
+ }
97
+ return result
98
+ }
99
+
100
+ /**
101
+ * 将错误列表按字段分组
102
+ * @param {Array<ValidateError>} errors - 校验错误列表
103
+ * @returns {Object|null} 以字段名为键,错误列表为值的对象;如果没有错误则返回 null
104
+ */
105
+ function convertFieldsError(errors) {
106
+ if (!errors || errors.length === 0) return null
107
+ const fields = {}
108
+ errors.forEach((error) => {
109
+ const field = error.field
110
+ fields[field] = fields[field] || []
111
+ fields[field].push(error)
112
+ })
113
+ return fields
114
+ }
115
+
116
+ /**
117
+ * 类型校验器集合
118
+ */
119
+ const typeValidators = {
120
+ /**
121
+ * 校验字符串类型
122
+ * @param {*} value - 待校验值
123
+ * @returns {boolean}
124
+ */
125
+ string(value) {
126
+ return typeof value === 'string'
127
+ },
128
+ /**
129
+ * 校验数字类型
130
+ * @param {*} value - 待校验值
131
+ * @returns {boolean}
132
+ */
133
+ number(value) {
134
+ return typeof value === 'number' && !isNaN(value)
135
+ },
136
+ /**
137
+ * 校验布尔类型
138
+ * @param {*} value - 待校验值
139
+ * @returns {boolean}
140
+ */
141
+ boolean(value) {
142
+ return typeof value === 'boolean'
143
+ },
144
+ /**
145
+ * 校验函数类型
146
+ * @param {*} value - 待校验值
147
+ * @returns {boolean}
148
+ */
149
+ method(value) {
150
+ return typeof value === 'function'
151
+ },
152
+ /**
153
+ * 校验正则表达式类型
154
+ * @param {*} value - 待校验值
155
+ * @returns {boolean}
156
+ */
157
+ regexp(value) {
158
+ return value instanceof RegExp
159
+ },
160
+ /**
161
+ * 校验对象类型(非数组)
162
+ * @param {*} value - 待校验值
163
+ * @returns {boolean}
164
+ */
165
+ object(value) {
166
+ return typeof value === 'object' && value !== null && !(value instanceof Array)
167
+ },
168
+ /**
169
+ * 校验整数类型
170
+ * @param {*} value - 待校验值
171
+ * @returns {boolean}
172
+ */
173
+ integer(value) {
174
+ return typeof value === 'number' && Number.isInteger(value)
175
+ },
176
+ /**
177
+ * 校验浮点数类型
178
+ * @param {*} value - 待校验值
179
+ * @returns {boolean}
180
+ */
181
+ float(value) {
182
+ return typeof value === 'number' && !Number.isInteger(value)
183
+ },
184
+ /**
185
+ * 校验数组类型
186
+ * @param {*} value - 待校验值
187
+ * @returns {boolean}
188
+ */
189
+ array(value) {
190
+ return Array.isArray(value)
191
+ },
192
+ /**
193
+ * 校验日期类型
194
+ * @param {*} value - 待校验值
195
+ * @returns {boolean}
196
+ */
197
+ date(value) {
198
+ return value instanceof Date && !isNaN(value.getTime())
199
+ },
200
+ /**
201
+ * 校验 URL 格式
202
+ * @param {*} value - 待校验值
203
+ * @returns {boolean}
204
+ */
205
+ url(value) {
206
+ return typeof value === 'string' && pattern.url.test(value)
207
+ },
208
+ /**
209
+ * 校验十六进制颜色格式
210
+ * @param {*} value - 待校验值
211
+ * @returns {boolean}
212
+ */
213
+ hex(value) {
214
+ return typeof value === 'string' && pattern.hex.test(value)
215
+ },
216
+ /**
217
+ * 校验邮箱格式
218
+ * @param {*} value - 待校验值
219
+ * @returns {boolean}
220
+ */
221
+ email(value) {
222
+ return typeof value === 'string' && pattern.email.test(value)
223
+ },
224
+ /**
225
+ * 校验 IPv4 地址格式
226
+ * @param {*} value - 待校验值
227
+ * @returns {boolean}
228
+ */
229
+ ipv4(value) {
230
+ return typeof value === 'string' && pattern.ipv4.test(value)
231
+ },
232
+ /**
233
+ * 校验 IPv6 地址格式
234
+ * @param {*} value - 待校验值
235
+ * @returns {boolean}
236
+ */
237
+ ipv6(value) {
238
+ return typeof value === 'string' && pattern.ipv6.test(value)
239
+ },
240
+ }
241
+
242
+ /**
243
+ * 校验错误类
244
+ */
245
+ class ValidateError extends Error {
246
+ /**
247
+ * 创建校验错误实例
248
+ * @param {string} message - 错误消息
249
+ * @param {string} field - 字段名
250
+ * @param {string} rule - 规则类型
251
+ * @param {string} [type='async-validator'] - 错误类型
252
+ */
253
+ constructor(message, field, rule, type = 'async-validator') {
254
+ super(message)
255
+ this.field = field
256
+ this.rule = rule
257
+ this.type = type
258
+ }
259
+ }
260
+
261
+ /**
262
+ * 规则校验器集合
263
+ */
264
+ const ruleValidators = {
265
+ /**
266
+ * 必填项校验
267
+ * @param {Object} rule - 校验规则
268
+ * @param {*} value - 待校验值
269
+ * @param {Object} source - 源数据对象
270
+ * @param {Array} errors - 错误收集数组
271
+ * @param {Object} options - 校验选项
272
+ */
273
+ required(rule, value, source, errors, options) {
274
+ if (rule.required && isEmptyValue(value)) {
275
+ errors.push(new ValidateError(format(rule.message || options.messages.required, rule.field), rule.field, 'required'))
276
+ }
277
+ },
278
+
279
+ /**
280
+ * 空白字符校验
281
+ * @param {Object} rule - 校验规则
282
+ * @param {*} value - 待校验值
283
+ * @param {Object} source - 源数据对象
284
+ * @param {Array} errors - 错误收集数组
285
+ * @param {Object} options - 校验选项
286
+ */
287
+ whitespace(rule, value, source, errors, options) {
288
+ if (rule.whitespace && typeof value === 'string' && value.trim() === '') {
289
+ errors.push(new ValidateError(format(rule.message || options.messages.whitespace, rule.field), rule.field, 'whitespace'))
290
+ }
291
+ },
292
+
293
+ /**
294
+ * 类型校验
295
+ * @param {Object} rule - 校验规则
296
+ * @param {*} value - 待校验值
297
+ * @param {Object} source - 源数据对象
298
+ * @param {Array} errors - 错误收集数组
299
+ * @param {Object} options - 校验选项
300
+ */
301
+ type(rule, value, source, errors, options) {
302
+ if (rule.type && typeValidators[rule.type]) {
303
+ const validator = typeValidators[rule.type]
304
+ if (!validator(value)) {
305
+ errors.push(new ValidateError(format(rule.message || options.messages.types[rule.type], rule.field, rule.type), rule.field, 'type'))
306
+ }
307
+ }
308
+ },
309
+
310
+ /**
311
+ * 正则表达式匹配校验
312
+ * @param {Object} rule - 校验规则
313
+ * @param {*} value - 待校验值
314
+ * @param {Object} source - 源数据对象
315
+ * @param {Array} errors - 错误收集数组
316
+ * @param {Object} options - 校验选项
317
+ */
318
+ pattern(rule, value, source, errors, options) {
319
+ if (rule.pattern && typeof value === 'string') {
320
+ const regexp = rule.pattern instanceof RegExp ? rule.pattern : new RegExp(rule.pattern)
321
+ if (!regexp.test(value)) {
322
+ errors.push(new ValidateError(format(rule.message || options.messages.pattern.mismatch, rule.field, value, rule.pattern), rule.field, 'pattern'))
323
+ }
324
+ }
325
+ },
326
+
327
+ /**
328
+ * 范围/长度校验
329
+ * @param {Object} rule - 校验规则
330
+ * @param {*} value - 待校验值
331
+ * @param {Object} source - 源数据对象
332
+ * @param {Array} errors - 错误收集数组
333
+ * @param {Object} options - 校验选项
334
+ */
335
+ range(rule, value, source, errors, options) {
336
+ if (typeof value === 'string' || Array.isArray(value)) {
337
+ const len = value.length
338
+ if (rule.len !== undefined && len !== rule.len) {
339
+ errors.push(new ValidateError(format(rule.message || options.messages[typeof value === 'string' ? 'string' : 'array'].len, rule.field, rule.len), rule.field, 'len'))
340
+ }
341
+ if (rule.min !== undefined && len < rule.min) {
342
+ errors.push(new ValidateError(format(rule.message || options.messages[typeof value === 'string' ? 'string' : 'array'].min, rule.field, rule.min), rule.field, 'min'))
343
+ }
344
+ if (rule.max !== undefined && len > rule.max) {
345
+ errors.push(new ValidateError(format(rule.message || options.messages[typeof value === 'string' ? 'string' : 'array'].max, rule.field, rule.max), rule.field, 'max'))
346
+ }
347
+ } else if (typeof value === 'number') {
348
+ if (rule.len !== undefined && value !== rule.len) {
349
+ errors.push(new ValidateError(format(rule.message || options.messages.number.len, rule.field, rule.len), rule.field, 'len'))
350
+ }
351
+ if (rule.min !== undefined && value < rule.min) {
352
+ errors.push(new ValidateError(format(rule.message || options.messages.number.min, rule.field, rule.min), rule.field, 'min'))
353
+ }
354
+ if (rule.max !== undefined && value > rule.max) {
355
+ errors.push(new ValidateError(format(rule.message || options.messages.number.max, rule.field, rule.max), rule.field, 'max'))
356
+ }
357
+ }
358
+ },
359
+
360
+ /**
361
+ * 枚举值校验
362
+ * @param {Object} rule - 校验规则
363
+ * @param {*} value - 待校验值
364
+ * @param {Object} source - 源数据对象
365
+ * @param {Array} errors - 错误收集数组
366
+ * @param {Object} options - 校验选项
367
+ */
368
+ enum(rule, value, source, errors, options) {
369
+ if (rule.enum && rule.enum.length > 0) {
370
+ if (!rule.enum.includes(value)) {
371
+ errors.push(new ValidateError(format(rule.message || options.messages.enum, rule.field, JSON.stringify(rule.enum)), rule.field, 'enum'))
372
+ }
373
+ }
374
+ },
375
+
376
+ /**
377
+ * 自定义校验器 (完全兼容 Element UI 风格: 同步返回 或 异步 callback)
378
+ * @param {Object} rule - 校验规则
379
+ * @param {*} value - 待校验值
380
+ * @param {Object} source - 源数据对象
381
+ * @param {Array} errors - 错误收集数组
382
+ * @param {Object} options - 校验选项
383
+ * @returns {Promise<void>}
384
+ */
385
+ validator(rule, value, source, errors, options) {
386
+ if (!rule.validator || typeof rule.validator !== 'function') {
387
+ return Promise.resolve()
388
+ }
389
+
390
+ return new Promise(async (resolve) => {
391
+ let called = false
392
+ const cb = (err) => {
393
+ if (called) return
394
+ called = true
395
+
396
+ if (err instanceof Error) {
397
+ errors.push(err)
398
+ } else if (typeof err === 'string') {
399
+ errors.push(new ValidateError(err, rule.field, 'validator'))
400
+ } else if (err) {
401
+ // 兼容其他真值错误
402
+ errors.push(new ValidateError(format(defaultMessages.default, rule.field), rule.field, 'validator'))
403
+ }
404
+ resolve()
405
+ }
406
+
407
+ try {
408
+ // 调用用户定义的 validator: (rule, value, callback)
409
+ // 注意:Element UI 标准签名只有3个参数,但我们传入 callback 即可
410
+ const res = await rule.validator(rule, value, cb)
411
+
412
+ // 处理同步返回的情况
413
+ // 如果用户没有调用 callback,而是直接返回了结果
414
+ if (!called) {
415
+ if (res === false) {
416
+ errors.push(new ValidateError(
417
+ typeof rule.message === 'function' ? rule.message(rule.field) : (rule.message || format(defaultMessages.default, rule.field)),
418
+ rule.field,
419
+ 'validator'
420
+ ))
421
+ } else if (res instanceof Error) {
422
+ errors.push(res)
423
+ }
424
+ // 同步完成,立即 resolve
425
+ resolve()
426
+ }
427
+ // 如果调用了 cb,cb 内部会调用 resolve()
428
+ } catch (e) {
429
+ if (!called) {
430
+ errors.push(e instanceof Error ? e : new ValidateError(String(e), rule.field, 'validator'))
431
+ resolve()
432
+ }
433
+ }
434
+ })
435
+ },
436
+ }
437
+
438
+ /**
439
+ * 校验 Schema 主类
440
+ */
441
+ class Schema {
442
+ /**
443
+ * 创建 Schema 实例
444
+ * @param {Object} descriptor - 校验描述符对象
445
+ * @param {Object} [options={}] - 配置选项
446
+ */
447
+ constructor(descriptor, options = {}) {
448
+ this.define(descriptor)
449
+ this.messages = Object.assign({}, defaultMessages, options.messages)
450
+ this.options = options
451
+ }
452
+
453
+ /**
454
+ * 定义校验描述符
455
+ * @param {Object} descriptor - 校验描述符对象
456
+ * @returns {Schema} 当前实例,支持链式调用
457
+ */
458
+ define(descriptor) {
459
+ this.descriptor = descriptor
460
+ return this
461
+ }
462
+
463
+ /**
464
+ * 设置或获取校验消息
465
+ * @param {Object} [messages] - 新的消息模板对象
466
+ * @returns {Object|void} 如果传入 messages 则无返回值,否则返回当前消息对象
467
+ */
468
+ messages(messages) {
469
+ if (messages) {
470
+ this.messages = Object.assign({}, this.messages, messages)
471
+ }
472
+ return this.messages
473
+ }
474
+
475
+ /**
476
+ * 执行校验
477
+ * @param {Object} source - 待校验的数据源
478
+ * @param {Object|Function} [o] - 校验选项或回调函数
479
+ * @param {Function} [cb] - 回调函数
480
+ * @returns {Promise<Object>} 校验结果 Promise
481
+ */
482
+ validate(source, o, cb) {
483
+ if (typeof o === 'function') {
484
+ cb = o
485
+ o = {}
486
+ }
487
+
488
+ const options = o || {}
489
+ const messages = Object.assign({}, this.messages, options.messages)
490
+ const keys = options.keys || Object.keys(this.descriptor)
491
+
492
+ options.messages = messages
493
+ options.first = options.first || false
494
+ options.firstFields = options.firstFields || false
495
+
496
+ const errors = []
497
+
498
+ // 用于收集所有字段的校验 Promise
499
+ const pendingValidations = []
500
+
501
+ keys.forEach((key) => {
502
+ const descriptor = this.descriptor[key]
503
+ const rules = Array.isArray(descriptor) ? descriptor : [descriptor]
504
+ const value = source[key]
505
+
506
+ // 为每个字段创建一个校验 Promise
507
+ const fieldValidationPromise = new Promise((resolveField) => {
508
+ const fieldErrors = []
509
+ let processedRuleCount = 0
510
+ const totalRules = rules.length
511
+
512
+ // 如果没有任何规则,直接 resolve
513
+ if (totalRules === 0) {
514
+ resolveField([])
515
+ return
516
+ }
517
+
518
+ rules.forEach((rule) => {
519
+ // 标准化 rule 对象
520
+ const ruleWithOptions = Object.assign({}, rule, {
521
+ key: key,
522
+ field: rule.field || key,
523
+ fullField: rule.fullField || rule.field || key,
524
+ })
525
+
526
+ const ruleErrors = []
527
+
528
+ // 运行内置同步校验器 (required, type, pattern, etc.)
529
+ // 这些仍然是同步执行的,直接填充 ruleErrors
530
+ Object.keys(ruleValidators).forEach((vKey) => {
531
+ // 跳过自定义 validator/asyncValidator,稍后单独处理
532
+ if (vKey === 'validator' || vKey === 'asyncValidator') return
533
+
534
+ if (rule.hasOwnProperty(vKey) || vKey === 'required') {
535
+ ruleValidators[vKey](ruleWithOptions, value, source, ruleErrors, options)
536
+ }
537
+ })
538
+
539
+ // 处理自定义 validator (支持异步)
540
+ let customValidatorPromise = Promise.resolve()
541
+
542
+ if (rule.validator && typeof rule.validator === 'function') {
543
+ // 使用我们改造后的 validator,它返回 Promise
544
+ customValidatorPromise = ruleValidators.validator(ruleWithOptions, value, source, ruleErrors, options)
545
+ } else if (rule.asyncValidator && typeof rule.asyncValidator === 'function') {
546
+ // 兼容旧的 asyncValidator 字段
547
+ customValidatorPromise = ruleValidators.asyncValidator(ruleWithOptions, value, source, ruleErrors, options)
548
+ }
549
+
550
+ // 等待自定义校验完成,然后汇总结果
551
+ customValidatorPromise.then(() => {
552
+ // 将当前规则的 errors 加入字段 errors
553
+ if (ruleErrors.length > 0) {
554
+ fieldErrors.push(...ruleErrors)
555
+ }
556
+
557
+ processedRuleCount++
558
+
559
+ // 如果所有规则都处理完了,resolve 该字段的 Promise
560
+ if (processedRuleCount === totalRules) {
561
+ resolveField(fieldErrors)
562
+ }
563
+ }).catch(err => {
564
+ // 防止 Promise reject 导致中断
565
+ console.error('Validation error:', err)
566
+ processedRuleCount++
567
+ if (processedRuleCount === totalRules) {
568
+ resolveField(fieldErrors)
569
+ }
570
+ })
571
+ })
572
+ })
573
+
574
+ pendingValidations.push(fieldValidationPromise.then((fieldErrors) => {
575
+ if (fieldErrors && fieldErrors.length > 0) {
576
+ errors.push(...fieldErrors)
577
+ }
578
+ }))
579
+ })
580
+
581
+ // 等待所有字段校验完成
582
+ return Promise.all(pendingValidations).then(() => {
583
+ if (errors.length > 0) {
584
+ const fields = convertFieldsError(errors)
585
+ if (cb) {
586
+ cb(errors, fields)
587
+ } else {
588
+ return Promise.reject({ errors, fields })
589
+ }
590
+ } else {
591
+ if (cb) {
592
+ cb(null, source)
593
+ } else {
594
+ return source
595
+ }
596
+ }
597
+ })
598
+ }
599
+
600
+ /**
601
+ * 校验指定字段
602
+ * @param {string|Array<string>} fields - 要校验的字段名或字段名数组
603
+ * @param {Object} source - 待校验的数据源
604
+ * @param {Object|Function} [o] - 校验选项或回调函数
605
+ * @param {Function} [cb] - 回调函数
606
+ * @returns {Promise<Object>} 校验结果 Promise
607
+ */
608
+ async validateField(fields, source, o, cb) {
609
+ if (typeof o === 'function') {
610
+ cb = o
611
+ o = {}
612
+ }
613
+
614
+ const options = o || {}
615
+ const keys = Array.isArray(fields) ? fields : [fields]
616
+
617
+ return this.validate(source, { ...options, keys }, cb)
618
+ }
619
+
620
+ /**
621
+ * 获取单个字段的规则
622
+ * @param {string} ruleKey - 规则键名
623
+ * @param {string} fullField - 完整字段名
624
+ * @returns {Array<Object>} 规则列表
625
+ */
626
+ getRule(ruleKey, fullField) {
627
+ const rule = this.descriptor[ruleKey]
628
+ if (rule) {
629
+ if (Array.isArray(rule)) {
630
+ return rule.map((r) => ({ ...r, field: fullField }))
631
+ }
632
+ return [{ ...rule, field: fullField }]
633
+ }
634
+ return []
635
+ }
636
+
637
+ /**
638
+ * 获取多个字段的规则
639
+ * @param {Array<string>} ruleKeys - 规则键名数组
640
+ * @param {Array<string>} fullFields - 完整字段名数组
641
+ * @returns {Array<Object>} 规则列表
642
+ */
643
+ getRules(ruleKeys, fullFields) {
644
+ const rules = []
645
+ ruleKeys.forEach((key, index) => {
646
+ const fieldRules = this.getRule(key, fullFields[index] || key)
647
+ rules.push(...fieldRules)
648
+ })
649
+ return rules
650
+ }
651
+ }
652
+
653
+ // 静态属性
654
+ Schema.pattern = pattern
655
+ Schema.messages = defaultMessages
656
+
657
+ // 导出
658
+ export default Schema
659
+ export { Schema, pattern, defaultMessages, typeValidators }
@@ -0,0 +1,39 @@
1
+ /**
2
+ * @module utils/browser
3
+ * @description 提供浏览器环境检测工具函数
4
+ */
5
+ import Vue from 'vue';
6
+
7
+ /**
8
+ * 检测当前浏览器是否为 IE
9
+ * @function isIE
10
+ * @memberof module:utils/browser
11
+ * @returns {Boolean} 如果是 IE 浏览器返回 true,否则返回 false
12
+ * @description 通过 document.documentMode 属性判断,仅在不处于服务端渲染(SSR)环境下有效
13
+ */
14
+ export const isIE = function() {
15
+ return !Vue.prototype.$isServer && !isNaN(Number(document.documentMode));
16
+ };
17
+
18
+ /**
19
+ * 检测当前浏览器是否为 Edge (旧版 EdgeHTML 内核)
20
+ * @function isEdge
21
+ * @memberof module:utils/browser
22
+ * @returns {Boolean} 如果是 Edge 浏览器返回 true,否则返回 false
23
+ * @description 通过 User-Agent 中包含 'Edge' 字符串判断,仅在不处于服务端渲染(SSR)环境下有效
24
+ * @note 注意:此方法主要检测基于 EdgeHTML 的旧版 Edge,新版 Chromium Edge 可能不被识别或需额外判断
25
+ */
26
+ export const isEdge = function() {
27
+ return !Vue.prototype.$isServer && navigator.userAgent.indexOf('Edge') > -1;
28
+ };
29
+
30
+ /**
31
+ * 检测当前浏览器是否为 Firefox
32
+ * @function isFirefox
33
+ * @memberof module:utils/browser
34
+ * @returns {Boolean} 如果是 Firefox 浏览器返回 true,否则返回 false
35
+ * @description 通过 User-Agent 中匹配 'firefox' 字符串判断(不区分大小写),仅在不处于服务端渲染(SSR)环境下有效
36
+ */
37
+ export const isFirefox = function() {
38
+ return !Vue.prototype.$isServer && !!window.navigator.userAgent.match(/firefox/i);
39
+ };