oxy-uni-ui 1.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 (355) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +13 -0
  3. package/attributes.json +1 -0
  4. package/components/common/AbortablePromise.ts +28 -0
  5. package/components/common/abstracts/_config.scss +7 -0
  6. package/components/common/abstracts/_function.scss +89 -0
  7. package/components/common/abstracts/_mixin.scss +385 -0
  8. package/components/common/abstracts/variable.scss +974 -0
  9. package/components/common/base64.ts +29 -0
  10. package/components/common/canvasHelper.ts +49 -0
  11. package/components/common/clickoutside.ts +25 -0
  12. package/components/common/event.ts +8 -0
  13. package/components/common/interceptor.ts +43 -0
  14. package/components/common/props.ts +51 -0
  15. package/components/common/util.ts +778 -0
  16. package/components/composables/index.ts +11 -0
  17. package/components/composables/useCell.ts +13 -0
  18. package/components/composables/useChildren.ts +113 -0
  19. package/components/composables/useCountDown.ts +138 -0
  20. package/components/composables/useLockScroll.ts +37 -0
  21. package/components/composables/useParent.ts +41 -0
  22. package/components/composables/usePopover.ts +176 -0
  23. package/components/composables/useQueue.ts +52 -0
  24. package/components/composables/useRaf.ts +37 -0
  25. package/components/composables/useTouch.ts +43 -0
  26. package/components/composables/useTranslate.ts +12 -0
  27. package/components/composables/useUpload.ts +364 -0
  28. package/components/oxy-action-sheet/index.scss +204 -0
  29. package/components/oxy-action-sheet/oxy-action-sheet.vue +155 -0
  30. package/components/oxy-action-sheet/types.ts +118 -0
  31. package/components/oxy-backtop/index.scss +25 -0
  32. package/components/oxy-backtop/oxy-backtop.vue +45 -0
  33. package/components/oxy-backtop/types.ts +37 -0
  34. package/components/oxy-badge/index.scss +63 -0
  35. package/components/oxy-badge/oxy-badge.vue +61 -0
  36. package/components/oxy-badge/types.ts +41 -0
  37. package/components/oxy-button/index.scss +336 -0
  38. package/components/oxy-button/oxy-button.vue +195 -0
  39. package/components/oxy-button/types.ts +133 -0
  40. package/components/oxy-calendar/index.scss +158 -0
  41. package/components/oxy-calendar/oxy-calendar.vue +451 -0
  42. package/components/oxy-calendar/types.ts +217 -0
  43. package/components/oxy-calendar-view/index.scss +0 -0
  44. package/components/oxy-calendar-view/month/index.scss +162 -0
  45. package/components/oxy-calendar-view/month/month.vue +389 -0
  46. package/components/oxy-calendar-view/month/types.ts +20 -0
  47. package/components/oxy-calendar-view/monthPanel/index.scss +89 -0
  48. package/components/oxy-calendar-view/monthPanel/month-panel.vue +374 -0
  49. package/components/oxy-calendar-view/monthPanel/types.ts +48 -0
  50. package/components/oxy-calendar-view/oxy-calendar-view.vue +111 -0
  51. package/components/oxy-calendar-view/types.ts +109 -0
  52. package/components/oxy-calendar-view/utils.ts +429 -0
  53. package/components/oxy-calendar-view/year/index.scss +153 -0
  54. package/components/oxy-calendar-view/year/types.ts +20 -0
  55. package/components/oxy-calendar-view/year/year.vue +202 -0
  56. package/components/oxy-calendar-view/yearPanel/index.scss +24 -0
  57. package/components/oxy-calendar-view/yearPanel/types.ts +38 -0
  58. package/components/oxy-calendar-view/yearPanel/year-panel.vue +135 -0
  59. package/components/oxy-card/index.scss +71 -0
  60. package/components/oxy-card/oxy-card.vue +37 -0
  61. package/components/oxy-card/types.ts +30 -0
  62. package/components/oxy-cell/index.scss +206 -0
  63. package/components/oxy-cell/oxy-cell.vue +140 -0
  64. package/components/oxy-cell/types.ts +111 -0
  65. package/components/oxy-cell-group/index.scss +56 -0
  66. package/components/oxy-cell-group/oxy-cell-group.vue +45 -0
  67. package/components/oxy-cell-group/types.ts +32 -0
  68. package/components/oxy-checkbox/index.scss +285 -0
  69. package/components/oxy-checkbox/oxy-checkbox.vue +177 -0
  70. package/components/oxy-checkbox/types.ts +68 -0
  71. package/components/oxy-checkbox-group/index.scss +20 -0
  72. package/components/oxy-checkbox-group/oxy-checkbox-group.vue +100 -0
  73. package/components/oxy-checkbox-group/types.ts +59 -0
  74. package/components/oxy-circle/index.scss +18 -0
  75. package/components/oxy-circle/oxy-circle.vue +296 -0
  76. package/components/oxy-circle/types.ts +54 -0
  77. package/components/oxy-col/index.scss +19 -0
  78. package/components/oxy-col/oxy-col.vue +49 -0
  79. package/components/oxy-col/types.ts +15 -0
  80. package/components/oxy-col-picker/index.scss +168 -0
  81. package/components/oxy-col-picker/oxy-col-picker.vue +498 -0
  82. package/components/oxy-col-picker/types.ts +166 -0
  83. package/components/oxy-collapse/index.scss +55 -0
  84. package/components/oxy-collapse/oxy-collapse.vue +151 -0
  85. package/components/oxy-collapse/types.ts +58 -0
  86. package/components/oxy-collapse-item/index.scss +90 -0
  87. package/components/oxy-collapse-item/oxy-collapse-item.vue +171 -0
  88. package/components/oxy-collapse-item/types.ts +48 -0
  89. package/components/oxy-config-provider/oxy-config-provider.vue +73 -0
  90. package/components/oxy-config-provider/types.ts +1052 -0
  91. package/components/oxy-count-down/index.scss +15 -0
  92. package/components/oxy-count-down/oxy-count-down.vue +60 -0
  93. package/components/oxy-count-down/types.ts +41 -0
  94. package/components/oxy-count-down/utils.ts +52 -0
  95. package/components/oxy-count-to/index.scss +7 -0
  96. package/components/oxy-count-to/oxy-count-to.vue +125 -0
  97. package/components/oxy-count-to/types.ts +117 -0
  98. package/components/oxy-curtain/index.scss +85 -0
  99. package/components/oxy-curtain/oxy-curtain.vue +172 -0
  100. package/components/oxy-curtain/types.ts +73 -0
  101. package/components/oxy-datetime-picker/index.scss +164 -0
  102. package/components/oxy-datetime-picker/oxy-datetime-picker.vue +801 -0
  103. package/components/oxy-datetime-picker/types.ts +231 -0
  104. package/components/oxy-datetime-picker-view/oxy-datetime-picker-view.vue +499 -0
  105. package/components/oxy-datetime-picker-view/types.ts +120 -0
  106. package/components/oxy-datetime-picker-view/util.ts +30 -0
  107. package/components/oxy-design-uni/oxy-design-uni.vue +5 -0
  108. package/components/oxy-divider/index.scss +100 -0
  109. package/components/oxy-divider/oxy-divider.vue +52 -0
  110. package/components/oxy-divider/types.ts +35 -0
  111. package/components/oxy-drop-menu/index.scss +86 -0
  112. package/components/oxy-drop-menu/oxy-drop-menu.vue +166 -0
  113. package/components/oxy-drop-menu/types.ts +38 -0
  114. package/components/oxy-drop-menu-item/index.scss +66 -0
  115. package/components/oxy-drop-menu-item/oxy-drop-menu-item.vue +221 -0
  116. package/components/oxy-drop-menu-item/types.ts +94 -0
  117. package/components/oxy-fab/index.scss +116 -0
  118. package/components/oxy-fab/oxy-fab.vue +276 -0
  119. package/components/oxy-fab/types.ts +66 -0
  120. package/components/oxy-floating-panel/index.scss +64 -0
  121. package/components/oxy-floating-panel/oxy-floating-panel.vue +140 -0
  122. package/components/oxy-floating-panel/type.ts +32 -0
  123. package/components/oxy-form/oxy-form.vue +207 -0
  124. package/components/oxy-form/types.ts +76 -0
  125. package/components/oxy-form-item/index.scss +18 -0
  126. package/components/oxy-form-item/oxy-form-item.vue +56 -0
  127. package/components/oxy-form-item/types.ts +16 -0
  128. package/components/oxy-gap/index.scss +9 -0
  129. package/components/oxy-gap/oxy-gap.vue +36 -0
  130. package/components/oxy-gap/types.ts +17 -0
  131. package/components/oxy-grid/index.scss +9 -0
  132. package/components/oxy-grid/oxy-grid.vue +106 -0
  133. package/components/oxy-grid/types.ts +50 -0
  134. package/components/oxy-grid-item/index.scss +148 -0
  135. package/components/oxy-grid-item/oxy-grid-item.vue +176 -0
  136. package/components/oxy-grid-item/types.ts +77 -0
  137. package/components/oxy-icon/index.scss +1230 -0
  138. package/components/oxy-icon/oxy-icon.vue +53 -0
  139. package/components/oxy-icon/oxy-icons.ttf +0 -0
  140. package/components/oxy-icon/types.ts +21 -0
  141. package/components/oxy-img/index.scss +19 -0
  142. package/components/oxy-img/oxy-img.vue +81 -0
  143. package/components/oxy-img/types.ts +61 -0
  144. package/components/oxy-img-cropper/index.scss +231 -0
  145. package/components/oxy-img-cropper/oxy-img-cropper.vue +664 -0
  146. package/components/oxy-img-cropper/types.ts +76 -0
  147. package/components/oxy-index-anchor/index.scss +35 -0
  148. package/components/oxy-index-anchor/oxy-index-anchor.vue +55 -0
  149. package/components/oxy-index-anchor/type.ts +9 -0
  150. package/components/oxy-index-bar/index.scss +39 -0
  151. package/components/oxy-index-bar/oxy-index-bar.vue +156 -0
  152. package/components/oxy-index-bar/type.ts +23 -0
  153. package/components/oxy-input/index.scss +323 -0
  154. package/components/oxy-input/oxy-input.vue +300 -0
  155. package/components/oxy-input/placeholder.scss +21 -0
  156. package/components/oxy-input/types.ts +189 -0
  157. package/components/oxy-input-number/index.scss +132 -0
  158. package/components/oxy-input-number/oxy-input-number.vue +464 -0
  159. package/components/oxy-input-number/types.ts +101 -0
  160. package/components/oxy-keyboard/constants.ts +81 -0
  161. package/components/oxy-keyboard/index.scss +102 -0
  162. package/components/oxy-keyboard/key/index.scss +79 -0
  163. package/components/oxy-keyboard/key/index.vue +76 -0
  164. package/components/oxy-keyboard/key/types.ts +11 -0
  165. package/components/oxy-keyboard/oxy-keyboard.vue +206 -0
  166. package/components/oxy-keyboard/types.ts +92 -0
  167. package/components/oxy-loading/index.scss +37 -0
  168. package/components/oxy-loading/oxy-loading.vue +90 -0
  169. package/components/oxy-loading/types.ts +22 -0
  170. package/components/oxy-loadmore/index.scss +39 -0
  171. package/components/oxy-loadmore/oxy-loadmore.vue +59 -0
  172. package/components/oxy-loadmore/types.ts +30 -0
  173. package/components/oxy-message-box/index.scss +108 -0
  174. package/components/oxy-message-box/index.ts +87 -0
  175. package/components/oxy-message-box/oxy-message-box.vue +291 -0
  176. package/components/oxy-message-box/types.ts +132 -0
  177. package/components/oxy-navbar/index.scss +93 -0
  178. package/components/oxy-navbar/oxy-navbar.vue +111 -0
  179. package/components/oxy-navbar/types.ts +52 -0
  180. package/components/oxy-navbar-capsule/index.scss +66 -0
  181. package/components/oxy-navbar-capsule/oxy-navbar-capsule.vue +35 -0
  182. package/components/oxy-navbar-capsule/types.ts +8 -0
  183. package/components/oxy-notice-bar/index.scss +68 -0
  184. package/components/oxy-notice-bar/oxy-notice-bar.vue +266 -0
  185. package/components/oxy-notice-bar/types.ts +67 -0
  186. package/components/oxy-notify/index.scss +34 -0
  187. package/components/oxy-notify/index.ts +61 -0
  188. package/components/oxy-notify/oxy-notify.vue +85 -0
  189. package/components/oxy-notify/types.ts +66 -0
  190. package/components/oxy-number-keyboard/index.scss +78 -0
  191. package/components/oxy-number-keyboard/key/index.scss +81 -0
  192. package/components/oxy-number-keyboard/key/index.vue +78 -0
  193. package/components/oxy-number-keyboard/key/types.ts +11 -0
  194. package/components/oxy-number-keyboard/oxy-number-keyboard.vue +151 -0
  195. package/components/oxy-number-keyboard/types.ts +83 -0
  196. package/components/oxy-overlay/index.scss +17 -0
  197. package/components/oxy-overlay/oxy-overlay.vue +47 -0
  198. package/components/oxy-overlay/types.ts +25 -0
  199. package/components/oxy-pagination/index.scss +57 -0
  200. package/components/oxy-pagination/oxy-pagination.vue +110 -0
  201. package/components/oxy-pagination/types.ts +41 -0
  202. package/components/oxy-password-input/index.scss +124 -0
  203. package/components/oxy-password-input/oxy-password-input.vue +49 -0
  204. package/components/oxy-password-input/types.ts +33 -0
  205. package/components/oxy-picker/index.scss +110 -0
  206. package/components/oxy-picker/oxy-picker.vue +412 -0
  207. package/components/oxy-picker/types.ts +189 -0
  208. package/components/oxy-picker-view/index.scss +92 -0
  209. package/components/oxy-picker-view/oxy-picker-view.vue +369 -0
  210. package/components/oxy-picker-view/types.ts +152 -0
  211. package/components/oxy-popover/index.scss +116 -0
  212. package/components/oxy-popover/oxy-popover.vue +180 -0
  213. package/components/oxy-popover/types.ts +69 -0
  214. package/components/oxy-popup/index.scss +84 -0
  215. package/components/oxy-popup/oxy-popup.vue +169 -0
  216. package/components/oxy-popup/types.ts +95 -0
  217. package/components/oxy-progress/index.scss +68 -0
  218. package/components/oxy-progress/oxy-progress.vue +197 -0
  219. package/components/oxy-progress/types.ts +35 -0
  220. package/components/oxy-radio/index.scss +301 -0
  221. package/components/oxy-radio/oxy-radio.vue +118 -0
  222. package/components/oxy-radio/types.ts +42 -0
  223. package/components/oxy-radio-group/index.scss +23 -0
  224. package/components/oxy-radio-group/oxy-radio-group.vue +51 -0
  225. package/components/oxy-radio-group/types.ts +39 -0
  226. package/components/oxy-rate/index.scss +25 -0
  227. package/components/oxy-rate/oxy-rate.vue +178 -0
  228. package/components/oxy-rate/types.ts +103 -0
  229. package/components/oxy-resize/index.scss +27 -0
  230. package/components/oxy-resize/oxy-resize.vue +144 -0
  231. package/components/oxy-resize/types.ts +6 -0
  232. package/components/oxy-root-portal/oxy-root-portal.vue +50 -0
  233. package/components/oxy-row/index.scss +10 -0
  234. package/components/oxy-row/oxy-row.vue +42 -0
  235. package/components/oxy-row/types.ts +16 -0
  236. package/components/oxy-search/index.scss +148 -0
  237. package/components/oxy-search/oxy-search.vue +187 -0
  238. package/components/oxy-search/types.ts +93 -0
  239. package/components/oxy-segmented/index.scss +101 -0
  240. package/components/oxy-segmented/oxy-segmented.vue +143 -0
  241. package/components/oxy-segmented/types.ts +71 -0
  242. package/components/oxy-select-picker/index.scss +102 -0
  243. package/components/oxy-select-picker/oxy-select-picker.vue +432 -0
  244. package/components/oxy-select-picker/types.ts +123 -0
  245. package/components/oxy-sidebar/index.scss +25 -0
  246. package/components/oxy-sidebar/oxy-sidebar.vue +63 -0
  247. package/components/oxy-sidebar/types.ts +38 -0
  248. package/components/oxy-sidebar-item/index.scss +97 -0
  249. package/components/oxy-sidebar-item/oxy-sidebar-item.vue +116 -0
  250. package/components/oxy-sidebar-item/types.ts +31 -0
  251. package/components/oxy-signature/index.scss +31 -0
  252. package/components/oxy-signature/oxy-signature.vue +630 -0
  253. package/components/oxy-signature/types.ts +108 -0
  254. package/components/oxy-skeleton/index.scss +96 -0
  255. package/components/oxy-skeleton/index.ts +1 -0
  256. package/components/oxy-skeleton/oxy-skeleton.vue +110 -0
  257. package/components/oxy-skeleton/types.ts +69 -0
  258. package/components/oxy-slider/index.scss +98 -0
  259. package/components/oxy-slider/oxy-slider.vue +356 -0
  260. package/components/oxy-slider/types.ts +138 -0
  261. package/components/oxy-sort-button/index.scss +89 -0
  262. package/components/oxy-sort-button/oxy-sort-button.vue +69 -0
  263. package/components/oxy-sort-button/types.ts +43 -0
  264. package/components/oxy-status-tip/images/collect.png +0 -0
  265. package/components/oxy-status-tip/images/content.png +0 -0
  266. package/components/oxy-status-tip/images/network.png +0 -0
  267. package/components/oxy-status-tip/images/search.png +0 -0
  268. package/components/oxy-status-tip/index.scss +37 -0
  269. package/components/oxy-status-tip/oxy-status-tip.vue +71 -0
  270. package/components/oxy-status-tip/types.ts +50 -0
  271. package/components/oxy-step/index.scss +235 -0
  272. package/components/oxy-step/oxy-step.vue +150 -0
  273. package/components/oxy-step/types.ts +33 -0
  274. package/components/oxy-steps/index.scss +10 -0
  275. package/components/oxy-steps/oxy-steps.vue +28 -0
  276. package/components/oxy-steps/types.ts +50 -0
  277. package/components/oxy-sticky/index.scss +9 -0
  278. package/components/oxy-sticky/oxy-sticky.vue +190 -0
  279. package/components/oxy-sticky/types.ts +13 -0
  280. package/components/oxy-sticky-box/index.scss +6 -0
  281. package/components/oxy-sticky-box/oxy-sticky-box.vue +155 -0
  282. package/components/oxy-sticky-box/types.ts +11 -0
  283. package/components/oxy-swipe-action/index.scss +22 -0
  284. package/components/oxy-swipe-action/oxy-swipe-action.vue +294 -0
  285. package/components/oxy-swipe-action/types.ts +40 -0
  286. package/components/oxy-swiper/index.scss +53 -0
  287. package/components/oxy-swiper/oxy-swiper.vue +318 -0
  288. package/components/oxy-swiper/types.ts +264 -0
  289. package/components/oxy-swiper-nav/index.scss +159 -0
  290. package/components/oxy-swiper-nav/oxy-swiper-nav.vue +37 -0
  291. package/components/oxy-swiper-nav/types.ts +42 -0
  292. package/components/oxy-switch/index.scss +58 -0
  293. package/components/oxy-switch/oxy-switch.vue +83 -0
  294. package/components/oxy-switch/types.ts +58 -0
  295. package/components/oxy-tab/index.scss +16 -0
  296. package/components/oxy-tab/oxy-tab.vue +88 -0
  297. package/components/oxy-tab/types.ts +30 -0
  298. package/components/oxy-tabbar/index.scss +62 -0
  299. package/components/oxy-tabbar/oxy-tabbar.vue +91 -0
  300. package/components/oxy-tabbar/types.ts +73 -0
  301. package/components/oxy-tabbar-item/index.scss +55 -0
  302. package/components/oxy-tabbar-item/oxy-tabbar-item.vue +99 -0
  303. package/components/oxy-tabbar-item/types.ts +51 -0
  304. package/components/oxy-table/index.scss +163 -0
  305. package/components/oxy-table/oxy-table.vue +283 -0
  306. package/components/oxy-table/types.ts +58 -0
  307. package/components/oxy-table-col/index.scss +46 -0
  308. package/components/oxy-table-col/oxy-table-col.vue +149 -0
  309. package/components/oxy-table-col/types.ts +54 -0
  310. package/components/oxy-tabs/index.scss +299 -0
  311. package/components/oxy-tabs/oxy-tabs.vue +443 -0
  312. package/components/oxy-tabs/types.ts +107 -0
  313. package/components/oxy-tag/index.scss +115 -0
  314. package/components/oxy-tag/oxy-tag.vue +148 -0
  315. package/components/oxy-tag/types.ts +81 -0
  316. package/components/oxy-text/index.scss +37 -0
  317. package/components/oxy-text/oxy-text.vue +139 -0
  318. package/components/oxy-text/types.ts +98 -0
  319. package/components/oxy-textarea/index.scss +340 -0
  320. package/components/oxy-textarea/oxy-textarea.vue +296 -0
  321. package/components/oxy-textarea/placeholder.scss +20 -0
  322. package/components/oxy-textarea/types.ts +288 -0
  323. package/components/oxy-toast/index.scss +75 -0
  324. package/components/oxy-toast/index.ts +92 -0
  325. package/components/oxy-toast/oxy-toast.vue +198 -0
  326. package/components/oxy-toast/types.ts +181 -0
  327. package/components/oxy-tooltip/index.scss +66 -0
  328. package/components/oxy-tooltip/oxy-tooltip.vue +141 -0
  329. package/components/oxy-tooltip/types.ts +107 -0
  330. package/components/oxy-transition/index.scss +95 -0
  331. package/components/oxy-transition/oxy-transition.vue +232 -0
  332. package/components/oxy-transition/types.ts +98 -0
  333. package/components/oxy-upload/index.scss +175 -0
  334. package/components/oxy-upload/oxy-upload.vue +673 -0
  335. package/components/oxy-upload/types.ts +391 -0
  336. package/components/oxy-video-preview/index.scss +34 -0
  337. package/components/oxy-video-preview/oxy-video-preview.vue +72 -0
  338. package/components/oxy-video-preview/types.ts +23 -0
  339. package/components/oxy-watermark/index.scss +18 -0
  340. package/components/oxy-watermark/oxy-watermark.vue +486 -0
  341. package/components/oxy-watermark/types.ts +76 -0
  342. package/dayjs/constant.js +26 -0
  343. package/dayjs/index.d.ts +430 -0
  344. package/dayjs/index.js +542 -0
  345. package/dayjs/locale/en.js +13 -0
  346. package/dayjs/utils.js +59 -0
  347. package/global.d.ts +101 -0
  348. package/index.ts +12 -0
  349. package/locale/index.ts +32 -0
  350. package/locale/lang/ar-SA.ts +133 -0
  351. package/locale/lang/en-US.ts +133 -0
  352. package/locale/lang/zh-CN.ts +137 -0
  353. package/package.json +1 -0
  354. package/tags.json +1 -0
  355. package/web-types.json +1 -0
@@ -0,0 +1,778 @@
1
+ import { AbortablePromise } from './AbortablePromise'
2
+
3
+ type NotUndefined<T> = T extends undefined ? never : T
4
+
5
+ /**
6
+ * 生成uuid
7
+ * @returns string
8
+ */
9
+ export function uuid() {
10
+ return s4() + s4() + s4() + s4() + s4() + s4() + s4() + s4()
11
+ }
12
+
13
+ function s4() {
14
+ return Math.floor((1 + Math.random()) * 0x10000)
15
+ .toString(16)
16
+ .substring(1)
17
+ }
18
+
19
+ /**
20
+ * @description 对num自动填充px
21
+ * @param {Number} num
22
+ * @return {string} num+px
23
+ */
24
+ export function addUnit(num: number | string) {
25
+ return Number.isNaN(Number(num)) ? `${num}` : `${num}px`
26
+ }
27
+
28
+ /**
29
+ * @description 判断target是否对象
30
+ * @param value
31
+ * @return {boolean}
32
+ */
33
+ export function isObj(value: any): value is object {
34
+ return Object.prototype.toString.call(value) === '[object Object]' || typeof value === 'object'
35
+ }
36
+
37
+ /**
38
+ * 获取目标原始类型
39
+ * @param target 任意类型
40
+ * @returns {string} type 数据类型
41
+ */
42
+ export function getType(target: unknown): string {
43
+ // 得到原生类型
44
+ const typeStr = Object.prototype.toString.call(target)
45
+ // 拿到类型值
46
+ const match = typeStr.match(/\[object (\w+)\]/)
47
+ const type = match && match.length ? match[1].toLowerCase() : ''
48
+ // 类型值转小写并返回
49
+ return type
50
+ }
51
+
52
+ /**
53
+ * @description 默认的外部格式化函数 - picker 组件
54
+ * @param items - 要格式化的数据项数组或单个数据项
55
+ * @param kv - 配置对象,包含 labelKey 作为键值
56
+ * @returns 格式化后的字符串
57
+ */
58
+ export const defaultDisplayFormat = function (items: any[] | Record<string, any>, kv?: { labelKey?: string }): string {
59
+ const labelKey: string = kv?.labelKey || 'value'
60
+
61
+ if (Array.isArray(items)) {
62
+ return items.map((item) => item[labelKey]).join(', ')
63
+ } else {
64
+ return items[labelKey]
65
+ }
66
+ }
67
+
68
+ /**
69
+ * @description 默认函数占位符 - pickerView组件
70
+ * @param value 值
71
+ * @return value
72
+ */
73
+ export const defaultFunction = <T>(value: T): T => value
74
+
75
+ /**
76
+ * @description 检查值是否不为空
77
+ * @param value 值
78
+ * @return {Boolean} 是否不为空
79
+ */
80
+ export const isDef = <T>(value: T): value is NonNullable<T> => value !== undefined && value !== null
81
+
82
+ /**
83
+ * @description 防止数字小于零
84
+ * @param {number} num
85
+ * @param {string} label 标签
86
+ */
87
+ export const checkNumRange = (num: number, label: string = 'value'): void => {
88
+ if (num < 0) {
89
+ throw new Error(`${label} shouldn't be less than zero`)
90
+ }
91
+ }
92
+
93
+ /**
94
+ * @description 防止 pixel 无意义
95
+ * @param {number} num
96
+ * @param {string} label 标签
97
+ */
98
+ export const checkPixelRange = (num: number, label: string = 'value'): void => {
99
+ if (num <= 0) {
100
+ throw new Error(`${label} should be greater than zero`)
101
+ }
102
+ }
103
+
104
+ /**
105
+ * 将 RGB 值转换为十六进制颜色代码。
106
+ * @param {number} r - 红色分量 (0-255)。
107
+ * @param {number} g - 绿色分量 (0-255)。
108
+ * @param {number} b - 蓝色分量 (0-255)。
109
+ * @returns {string} 十六进制颜色代码 (#RRGGBB)。
110
+ */
111
+ export function rgbToHex(r: number, g: number, b: number): string {
112
+ // 将 RGB 分量组合成一个十六进制数。
113
+ const hex = ((r << 16) | (g << 8) | b).toString(16)
114
+
115
+ // 使用零填充十六进制数,确保它有 6 位数字(RGB 范围)。
116
+ const paddedHex = '#' + '0'.repeat(Math.max(0, 6 - hex.length)) + hex
117
+
118
+ return paddedHex
119
+ }
120
+
121
+ /**
122
+ * 将十六进制颜色代码转换为 RGB 颜色数组。
123
+ * @param hex 十六进制颜色代码(例如:'#RRGGBB')
124
+ * @returns 包含红、绿、蓝三个颜色分量的数组
125
+ */
126
+ export function hexToRgb(hex: string): number[] {
127
+ const rgb: number[] = []
128
+
129
+ // 从第一个字符开始,每两个字符代表一个颜色分量
130
+ for (let i = 1; i < 7; i += 2) {
131
+ // 将两个字符的十六进制转换为十进制,并添加到 rgb 数组中
132
+ rgb.push(parseInt('0x' + hex.slice(i, i + 2), 16))
133
+ }
134
+
135
+ return rgb
136
+ }
137
+
138
+ /**
139
+ * 计算渐变色的中间变量数组。
140
+ * @param {string} startColor 开始颜色
141
+ * @param {string} endColor 结束颜色
142
+ * @param {number} step 获取渲染位置,默认为中间位置
143
+ * @returns {string[]} 渐变色中间颜色变量数组
144
+ */
145
+ export const gradient = (startColor: string, endColor: string, step: number = 2): string[] => {
146
+ // 将hex转换为rgb
147
+ const sColor: number[] = hexToRgb(startColor)
148
+ const eColor: number[] = hexToRgb(endColor)
149
+
150
+ // 计算R\G\B每一步的差值
151
+ const rStep: number = (eColor[0] - sColor[0]) / step
152
+ const gStep: number = (eColor[1] - sColor[1]) / step
153
+ const bStep: number = (eColor[2] - sColor[2]) / step
154
+
155
+ const gradientColorArr: string[] = []
156
+ for (let i = 0; i < step; i++) {
157
+ // 计算每一步的hex值
158
+ gradientColorArr.push(
159
+ rgbToHex(parseInt(String(rStep * i + sColor[0])), parseInt(String(gStep * i + sColor[1])), parseInt(String(bStep * i + sColor[2])))
160
+ )
161
+ }
162
+ return gradientColorArr
163
+ }
164
+
165
+ /**
166
+ * 确保数值不超出指定范围。
167
+ * @param {number} num 要限制范围的数值
168
+ * @param {number} min 最小范围
169
+ * @param {number} max 最大范围
170
+ * @returns {number} 在指定范围内的数值
171
+ */
172
+ export const range = (num: number, min: number, max: number): number => {
173
+ // 使用 Math.min 和 Math.max 保证 num 不会超出指定范围
174
+ return Math.min(Math.max(num, min), max)
175
+ }
176
+
177
+ /**
178
+ * 比较两个值是否相等。
179
+ * @param {any} value1 第一个值
180
+ * @param {any} value2 第二个值
181
+ * @returns {boolean} 如果值相等则为 true,否则为 false
182
+ */
183
+ export const isEqual = (value1: any, value2: any): boolean => {
184
+ // 使用严格相等运算符比较值是否相等
185
+ if (value1 === value2) {
186
+ return true
187
+ }
188
+
189
+ // 如果其中一个值不是数组,则认为值不相等
190
+ if (!Array.isArray(value1) || !Array.isArray(value2)) {
191
+ return false
192
+ }
193
+
194
+ // 如果数组长度不相等,则认为值不相等
195
+ if (value1.length !== value2.length) {
196
+ return false
197
+ }
198
+
199
+ // 逐个比较数组元素是否相等
200
+ for (let i = 0; i < value1.length; ++i) {
201
+ if (value1[i] !== value2[i]) {
202
+ return false
203
+ }
204
+ }
205
+
206
+ // 所有比较均通过,则认为值相等
207
+ return true
208
+ }
209
+
210
+ /**
211
+ * 在数字前补零,使其达到指定长度。
212
+ * @param {number | string} number 要补零的数字
213
+ * @param {number} length 目标长度,默认为 2
214
+ * @returns {string} 补零后的结果
215
+ */
216
+ export const padZero = (number: number | string, length: number = 2): string => {
217
+ // 将输入转换为字符串
218
+ let numStr: string = number.toString()
219
+
220
+ // 在数字前补零,直到达到指定长度
221
+ while (numStr.length < length) {
222
+ numStr = '0' + numStr
223
+ }
224
+
225
+ return numStr
226
+ }
227
+
228
+ /** @description 全局变量id */
229
+ export const context = {
230
+ id: 1000
231
+ }
232
+
233
+ export type RectResultType<T extends boolean> = T extends true ? UniApp.NodeInfo[] : UniApp.NodeInfo
234
+
235
+ /**
236
+ * 获取节点信息
237
+ * @param selector 节点选择器 #id,.class
238
+ * @param all 是否返回所有 selector 对应的节点
239
+ * @param scope 作用域(支付宝小程序无效)
240
+ * @param useFields 是否使用 fields 方法获取节点信息
241
+ * @returns 节点信息或节点信息数组
242
+ */
243
+ export function getRect<T extends boolean>(selector: string, all: T, scope?: any, useFields?: boolean): Promise<RectResultType<T>> {
244
+ return new Promise<RectResultType<T>>((resolve, reject) => {
245
+ let query: UniNamespace.SelectorQuery | null = null
246
+ if (scope) {
247
+ query = uni.createSelectorQuery().in(scope)
248
+ } else {
249
+ query = uni.createSelectorQuery()
250
+ }
251
+
252
+ const method = all ? 'selectAll' : 'select'
253
+
254
+ const callback = (rect: UniApp.NodeInfo | UniApp.NodeInfo[]) => {
255
+ if (all && isArray(rect) && rect.length > 0) {
256
+ resolve(rect as RectResultType<T>)
257
+ } else if (!all && rect) {
258
+ resolve(rect as RectResultType<T>)
259
+ } else {
260
+ reject(new Error('No nodes found'))
261
+ }
262
+ }
263
+
264
+ if (useFields) {
265
+ query[method](selector).fields({ size: true, node: true }, callback).exec()
266
+ } else {
267
+ query[method](selector).boundingClientRect(callback).exec()
268
+ }
269
+ })
270
+ }
271
+
272
+ /**
273
+ * 将驼峰命名转换为短横线命名。
274
+ * @param {string} word 待转换的词条
275
+ * @returns {string} 转换后的结果
276
+ */
277
+ export function kebabCase(word: string): string {
278
+ // 使用正则表达式匹配所有大写字母,并在前面加上短横线,然后转换为小写
279
+ const newWord: string = word
280
+ .replace(/[A-Z]/g, function (match) {
281
+ return '-' + match
282
+ })
283
+ .toLowerCase()
284
+
285
+ return newWord
286
+ }
287
+
288
+ /**
289
+ * 将短横线链接转换为驼峰命名
290
+ * @param word 需要转换的短横线链接
291
+ * @returns 转换后的驼峰命名字符串
292
+ */
293
+ export function camelCase(word: string): string {
294
+ return word.replace(/-(\w)/g, (_, c) => c.toUpperCase())
295
+ }
296
+
297
+ /**
298
+ * 检查给定值是否为数组。
299
+ * @param {any} value 要检查的值
300
+ * @returns {boolean} 如果是数组则返回 true,否则返回 false
301
+ */
302
+ export function isArray(value: any): value is Array<any> {
303
+ // 如果 Array.isArray 函数可用,直接使用该函数检查
304
+ if (typeof Array.isArray === 'function') {
305
+ return Array.isArray(value)
306
+ }
307
+ // 否则,使用对象原型的 toString 方法进行检查
308
+ return Object.prototype.toString.call(value) === '[object Array]'
309
+ }
310
+
311
+ /**
312
+ * 检查给定值是否为函数。
313
+ * @param {any} value 要检查的值
314
+ * @returns {boolean} 如果是函数则返回 true,否则返回 false
315
+ */
316
+ // eslint-disable-next-line @typescript-eslint/ban-types
317
+ export function isFunction<T extends Function>(value: any): value is T {
318
+ return getType(value) === 'function' || getType(value) === 'asyncfunction'
319
+ }
320
+
321
+ /**
322
+ * 检查给定值是否为字符串。
323
+ * @param {unknown} value 要检查的值
324
+ * @returns {value is string} 如果是字符串则返回 true,否则返回 false
325
+ */
326
+ export function isString(value: unknown): value is string {
327
+ return getType(value) === 'string'
328
+ }
329
+
330
+ /**
331
+ * 否是数值
332
+ * @param {*} value
333
+ */
334
+ export function isNumber(value: any): value is number {
335
+ return getType(value) === 'number'
336
+ }
337
+
338
+ /**
339
+ * 检查给定值是否为 Promise 对象。
340
+ * @param {unknown} value 要检查的值
341
+ * @returns {value is Promise<any>} 如果是 Promise 对象则返回 true,否则返回 false
342
+ */
343
+ export function isPromise(value: unknown): value is Promise<any> {
344
+ // 先将 value 断言为 object 类型
345
+ if (isObj(value) && isDef(value)) {
346
+ // 然后进一步检查 value 是否具有 then 和 catch 方法,并且它们是函数类型
347
+ return isFunction((value as Promise<any>).then) && isFunction((value as Promise<any>).catch)
348
+ }
349
+ return false // 如果 value 不是对象类型,则肯定不是 Promise
350
+ }
351
+
352
+ /**
353
+ * 检查给定的值是否为布尔类型
354
+ * @param value 要检查的值
355
+ * @returns 如果值为布尔类型,则返回true,否则返回false
356
+ */
357
+ export function isBoolean(value: any): value is boolean {
358
+ return typeof value === 'boolean'
359
+ }
360
+
361
+ export function isUndefined(value: any): value is undefined {
362
+ return typeof value === 'undefined'
363
+ }
364
+
365
+ export function isNotUndefined<T>(value: T): value is NotUndefined<T> {
366
+ return !isUndefined(value)
367
+ }
368
+
369
+ /**
370
+ * 检查给定的值是否为奇数
371
+ * @param value 要检查的值
372
+ * @returns
373
+ */
374
+ export function isOdd(value: number): boolean {
375
+ if (typeof value !== 'number') {
376
+ throw new Error('输入必须为数字')
377
+ }
378
+
379
+ // 使用取模运算符来判断是否为奇数
380
+ // 如果 number 除以 2 的余数为 1,就是奇数
381
+ // 否则是偶数
382
+ return value % 2 === 1
383
+ }
384
+
385
+ /**
386
+ * 是否为base64图片
387
+ * @param {string} url
388
+ * @return
389
+ */
390
+ export function isBase64Image(url: string) {
391
+ // 使用正则表达式检查URL是否以"data:image"开头,这是Base64图片的常见前缀
392
+ return /^data:image\/(png|jpg|jpeg|gif|bmp);base64,/.test(url)
393
+ }
394
+
395
+ /**
396
+ * 将外部传入的样式格式化为可读的 CSS 样式。
397
+ * @param {object | object[]} styles 外部传入的样式对象或数组
398
+ * @returns {string} 格式化后的 CSS 样式字符串
399
+ */
400
+ export function objToStyle(styles: Record<string, any> | Record<string, any>[]): string {
401
+ // 如果 styles 是数组类型
402
+ if (isArray(styles)) {
403
+ // 使用过滤函数去除空值和 null 值的元素
404
+ // 对每个非空元素递归调用 objToStyle,然后通过分号连接
405
+ const result = styles
406
+ .filter(function (item) {
407
+ return item != null && item !== ''
408
+ })
409
+ .map(function (item) {
410
+ return objToStyle(item)
411
+ })
412
+ .join(';')
413
+
414
+ // 如果结果不为空,确保末尾有分号
415
+ return result ? (result.endsWith(';') ? result : result + ';') : ''
416
+ }
417
+
418
+ if (isString(styles)) {
419
+ // 如果是字符串且不为空,确保末尾有分号
420
+ return styles ? (styles.endsWith(';') ? styles : styles + ';') : ''
421
+ }
422
+
423
+ // 如果 styles 是对象类型
424
+ if (isObj(styles)) {
425
+ // 使用 Object.keys 获取所有属性名
426
+ // 使用过滤函数去除值为 null 或空字符串的属性
427
+ // 对每个属性名和属性值进行格式化,通过分号连接
428
+ const result = Object.keys(styles)
429
+ .filter(function (key) {
430
+ return styles[key] != null && styles[key] !== ''
431
+ })
432
+ .map(function (key) {
433
+ // 使用 kebabCase 函数将属性名转换为 kebab-case 格式
434
+ // 将属性名和属性值格式化为 CSS 样式的键值对
435
+ return [kebabCase(key), styles[key]].join(':')
436
+ })
437
+ .join(';')
438
+
439
+ // 如果结果不为空,确保末尾有分号
440
+ return result ? (result.endsWith(';') ? result : result + ';') : ''
441
+ }
442
+ // 如果 styles 不是对象也不是数组,则直接返回
443
+ return ''
444
+ }
445
+
446
+ /**
447
+ * 判断一个对象是否包含任何字段
448
+ * @param obj 要检查的对象
449
+ * @returns {boolean} 如果对象为空(不包含任何字段)则返回 true,否则返回 false
450
+ */
451
+ export function hasFields(obj: unknown): boolean {
452
+ // 如果不是对象类型或为 null,则认为没有字段
453
+ if (!isObj(obj) || obj === null) {
454
+ return false
455
+ }
456
+
457
+ // 使用 Object.keys 检查对象是否有属性
458
+ return Object.keys(obj).length > 0
459
+ }
460
+
461
+ /**
462
+ * 判断一个对象是否为空对象(不包含任何字段)
463
+ * @param obj 要检查的对象
464
+ * @returns {boolean} 如果对象为空(不包含任何字段)则返回 true,否则返回 false
465
+ */
466
+ export function isEmptyObj(obj: unknown): boolean {
467
+ return !hasFields(obj)
468
+ }
469
+
470
+ export const requestAnimationFrame = (cb = () => {}) => {
471
+ return new AbortablePromise((resolve) => {
472
+ const timer = setInterval(() => {
473
+ clearInterval(timer)
474
+ resolve(true)
475
+ cb()
476
+ }, 1000 / 30)
477
+ })
478
+ }
479
+
480
+ /**
481
+ * 暂停指定时间函数
482
+ * @param ms 延迟时间
483
+ * @returns
484
+ */
485
+ export const pause = (ms: number = 1000 / 30) => {
486
+ return new AbortablePromise((resolve) => {
487
+ const timer = setTimeout(() => {
488
+ clearTimeout(timer)
489
+ resolve(true)
490
+ }, ms)
491
+ })
492
+ }
493
+
494
+ /**
495
+ * 深拷贝函数,用于将对象进行完整复制。
496
+ * @param obj 要深拷贝的对象
497
+ * @param cache 用于缓存已复制的对象,防止循环引用
498
+ * @returns 深拷贝后的对象副本
499
+ */
500
+ export function deepClone<T>(obj: T, cache: Map<any, any> = new Map()): T {
501
+ // 如果对象为 null 或或者不是对象类型,则直接返回该对象
502
+ if (obj === null || typeof obj !== 'object') {
503
+ return obj
504
+ }
505
+
506
+ // 处理特殊对象类型:日期、正则表达式、错误对象
507
+ if (isDate(obj)) {
508
+ return new Date(obj.getTime()) as any
509
+ }
510
+ if (obj instanceof RegExp) {
511
+ return new RegExp(obj.source, obj.flags) as any
512
+ }
513
+ if (obj instanceof Error) {
514
+ const errorCopy = new Error(obj.message) as any
515
+ errorCopy.stack = obj.stack
516
+ return errorCopy
517
+ }
518
+
519
+ // 检查缓存中是否已存在该对象的复制
520
+ if (cache.has(obj)) {
521
+ return cache.get(obj)
522
+ }
523
+
524
+ // 根据原始对象的类型创建对应的空对象或数组
525
+ const copy: any = Array.isArray(obj) ? [] : {}
526
+
527
+ // 将当前对象添加到缓存中
528
+ cache.set(obj, copy)
529
+
530
+ // 递归地深拷贝对象的每个属性
531
+ for (const key in obj) {
532
+ if (Object.prototype.hasOwnProperty.call(obj, key)) {
533
+ copy[key] = deepClone(obj[key], cache)
534
+ }
535
+ }
536
+
537
+ return copy as T
538
+ }
539
+
540
+ /**
541
+ * 深度合并两个对象。
542
+ * @param target 目标对象,将合并的结果存放在此对象中
543
+ * @param source 源对象,要合并到目标对象的对象
544
+ * @returns 合并后的目标对象
545
+ */
546
+ export function deepMerge<T extends Record<string, any>>(target: T, source: Record<string, any>): T {
547
+ // 深拷贝目标对象,避免修改原始对象
548
+ target = deepClone(target)
549
+
550
+ // 检查目标和源是否都是对象类型
551
+ if (typeof target !== 'object' || typeof source !== 'object') {
552
+ throw new Error('Both target and source must be objects.')
553
+ }
554
+
555
+ // 遍历源对象的属性
556
+ for (const prop in source) {
557
+ // eslint-disable-next-line no-prototype-builtins
558
+ if (!source.hasOwnProperty(prop))
559
+ continue
560
+ // 使用类型断言,告诉 TypeScript 这是有效的属性
561
+ ;(target as Record<string, any>)[prop] = source[prop]
562
+ }
563
+
564
+ return target
565
+ }
566
+
567
+ /**
568
+ * 深度合并两个对象。
569
+ * @param target
570
+ * @param source
571
+ * @returns
572
+ */
573
+ export function deepAssign(target: Record<string, any>, source: Record<string, any>): Record<string, any> {
574
+ Object.keys(source).forEach((key) => {
575
+ const targetValue = target[key]
576
+ const newObjValue = source[key]
577
+ if (isObj(targetValue) && isObj(newObjValue)) {
578
+ deepAssign(targetValue, newObjValue)
579
+ } else {
580
+ target[key] = newObjValue
581
+ }
582
+ })
583
+ return target
584
+ }
585
+
586
+ /**
587
+ * 构建带参数的URL
588
+ * @param baseUrl 基础URL
589
+ * @param params 参数对象,键值对表示要添加到URL的参数
590
+ * @returns 返回带有参数的URL
591
+ */
592
+ export function buildUrlWithParams(baseUrl: string, params: Record<string, string>) {
593
+ // 将参数对象转换为查询字符串
594
+ const queryString = Object.entries(params)
595
+ .map(([key, value]) => `${key}=${encodeURIComponent(value)}`)
596
+ .join('&')
597
+
598
+ // 检查基础URL是否已包含查询字符串,并选择适当的分隔符
599
+ const separator = baseUrl.includes('?') ? '&' : '?'
600
+
601
+ // 返回带有参数的URL
602
+ return `${baseUrl}${separator}${queryString}`
603
+ }
604
+
605
+ type DebounceOptions = {
606
+ leading?: boolean // 是否在延迟时间开始时调用函数
607
+ trailing?: boolean // 是否在延迟时间结束时调用函数
608
+ }
609
+
610
+ export function debounce<T extends (...args: any[]) => any>(func: T, wait: number, options: DebounceOptions = {}): T {
611
+ let timeoutId: ReturnType<typeof setTimeout> | null = null
612
+ let lastArgs: any[] | undefined
613
+ let lastThis: any
614
+ let result: ReturnType<T> | undefined
615
+ const leading = isDef(options.leading) ? options.leading : false
616
+ const trailing = isDef(options.trailing) ? options.trailing : true
617
+
618
+ function invokeFunc() {
619
+ if (lastArgs !== undefined) {
620
+ result = func.apply(lastThis, lastArgs)
621
+ lastArgs = undefined
622
+ }
623
+ }
624
+
625
+ function startTimer() {
626
+ timeoutId = setTimeout(() => {
627
+ timeoutId = null
628
+ if (trailing) {
629
+ invokeFunc()
630
+ }
631
+ }, wait)
632
+ }
633
+
634
+ function cancelTimer() {
635
+ if (timeoutId !== null) {
636
+ clearTimeout(timeoutId)
637
+ timeoutId = null
638
+ }
639
+ }
640
+
641
+ function debounced(this: any, ...args: Parameters<T>): ReturnType<T> | undefined {
642
+ lastArgs = args
643
+ lastThis = this
644
+
645
+ if (timeoutId === null) {
646
+ if (leading) {
647
+ invokeFunc()
648
+ }
649
+ startTimer()
650
+ } else if (trailing) {
651
+ cancelTimer()
652
+ startTimer()
653
+ }
654
+
655
+ return result
656
+ }
657
+
658
+ return debounced as T
659
+ }
660
+
661
+ // eslint-disable-next-line @typescript-eslint/ban-types
662
+ export function throttle(func: Function, wait: number): Function {
663
+ let timeout: ReturnType<typeof setTimeout> | null = null
664
+ let previous: number = 0
665
+
666
+ const throttled = function (this: any, ...args: any[]) {
667
+ const now = Date.now()
668
+ const remaining = wait - (now - previous)
669
+
670
+ if (remaining <= 0) {
671
+ if (timeout) {
672
+ clearTimeout(timeout)
673
+ timeout = null
674
+ }
675
+ previous = now
676
+ func.apply(this, args)
677
+ } else if (!timeout) {
678
+ timeout = setTimeout(() => {
679
+ previous = Date.now()
680
+ timeout = null
681
+ func.apply(this, args)
682
+ }, remaining)
683
+ }
684
+ }
685
+
686
+ return throttled
687
+ }
688
+
689
+ /**
690
+ * 根据属性路径获取对象中的属性值
691
+ * @param obj 目标对象
692
+ * @param path 属性路径,可以是字符串或字符串数组
693
+ * @returns 属性值,如果属性不存在或中间的属性为 null 或 undefined,则返回 undefined
694
+ */
695
+ export const getPropByPath = (obj: any, path: string): any => {
696
+ const keys: string[] = path.split('.')
697
+
698
+ try {
699
+ return keys.reduce((acc: any, key: string) => (acc !== undefined && acc !== null ? acc[key] : undefined), obj)
700
+ } catch (error) {
701
+ return undefined
702
+ }
703
+ }
704
+
705
+ /**
706
+ * 检查一个值是否为Date类型
707
+ * @param val 要检查的值
708
+ * @returns 如果值是Date类型,则返回true,否则返回false
709
+ */
710
+ export const isDate = (val: unknown): val is Date => Object.prototype.toString.call(val) === '[object Date]' && !Number.isNaN((val as Date).getTime())
711
+
712
+ /**
713
+ * 检查提供的URL是否为视频链接。
714
+ * @param url 需要检查的URL字符串。
715
+ * @returns 返回一个布尔值,如果URL是视频链接则为true,否则为false。
716
+ */
717
+ export function isVideoUrl(url: string): boolean {
718
+ // 使用正则表达式匹配视频文件类型的URL
719
+ const videoRegex = /\.(ogm|webm|ogv|asx|m4v|mp4|mpg|mpeg|dat|asf|avi|rm|rmvb|mov|wmv|flv|mkv|video)(?=$|[?#])/i
720
+ return videoRegex.test(url)
721
+ }
722
+
723
+ /**
724
+ * 检查提供的URL是否为图片URL。
725
+ * @param url 待检查的URL字符串。
726
+ * @returns 返回一个布尔值,如果URL是图片格式,则为true;否则为false。
727
+ */
728
+ export function isImageUrl(url: string): boolean {
729
+ // 使用正则表达式匹配图片URL
730
+ const imageRegex = /\.(xbm|tif|pjp|apng|svgz|jpeg|jpg|heif|ico|tiff|heic|pjpeg|avif|gif|png|svg|webp|jfif|bmp|dpg|image)(?=$|[?#])/i
731
+ return imageRegex.test(url)
732
+ }
733
+
734
+ /**
735
+ * 判断环境是否是H5
736
+ */
737
+ export const isH5 = (() => {
738
+ let isH5 = false
739
+ // #ifdef H5
740
+ isH5 = true
741
+ // #endif
742
+ return isH5
743
+ })()
744
+
745
+ /**
746
+ * 剔除对象中的某些属性
747
+ * @param obj
748
+ * @param predicate
749
+ * @returns
750
+ */
751
+ export function omitBy<O extends Record<string, any>>(obj: O, predicate: (value: any, key: keyof O) => boolean): Partial<O> {
752
+ const newObj = deepClone(obj)
753
+ Object.keys(newObj).forEach((key) => predicate(newObj[key], key) && delete newObj[key]) // 遍历对象的键,删除值为不满足predicate的字段
754
+ return newObj
755
+ }
756
+
757
+ /**
758
+ * 缓动函数,用于在动画或过渡效果中根据时间参数计算当前值
759
+ * @param t 当前时间,通常是从动画开始经过的时间
760
+ * @param b 初始值,动画属性的初始值
761
+ * @param c 变化量,动画属性的目标值与初始值的差值
762
+ * @param d 持续时间,动画持续的总时间长度
763
+ * @returns 计算出的当前值
764
+ */
765
+ export function easingFn(t: number = 0, b: number = 0, c: number = 0, d: number = 0): number {
766
+ return (c * (-Math.pow(2, (-10 * t) / d) + 1) * 1024) / 1023 + b
767
+ }
768
+
769
+ /**
770
+ * 从数组中寻找最接近目标值的元素
771
+ *
772
+ * @param arr 数组
773
+ * @param target 目标值
774
+ * @returns 最接近目标值的元素
775
+ */
776
+ export function closest(arr: number[], target: number) {
777
+ return arr.reduce((prev, curr) => (Math.abs(curr - target) < Math.abs(prev - target) ? curr : prev))
778
+ }