v-uni-app-ui 1.0.4 → 1.0.6

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 (89) hide show
  1. package/README.md +62 -82
  2. package/dist/v-uni-app-ui.css +1 -0
  3. package/dist/v-uni-app-ui.es.js +6569 -0
  4. package/dist/v-uni-app-ui.umd.js +7 -0
  5. package/package.json +17 -5
  6. package/components/config/css/basic.scss +0 -19
  7. package/components/config/interface/basic-type.js +0 -16
  8. package/components/config/interface/components-interface.ts +0 -0
  9. package/components/config/interface/monitor/components/input-monitor.js +0 -0
  10. package/components/config/interface/monitor/property-monitor.ts +0 -136
  11. package/components/config/interface/props/basic-props.ts +0 -88
  12. package/components/config/interface/props/components/button-props.ts +0 -85
  13. package/components/config/interface/props/components/input-props.ts +0 -69
  14. package/components/config/interface/props/props-tools.ts +0 -64
  15. package/components/config/style/basic.js +0 -346
  16. package/components/config/style/component-registry.js +0 -142
  17. package/components/config/style/components/button-style.js +0 -160
  18. package/components/config/style/components/input-style.js +0 -98
  19. package/components/config/style/components-style.js +0 -622
  20. package/components/config/style/property-mapper.js +0 -377
  21. package/components/config/style/pseudo-processor.js +0 -213
  22. package/components/config.js +0 -123
  23. package/components/icon/iconfont.css +0 -87
  24. package/components/icon/iconfont.js +0 -1
  25. package/components/icon/iconfont.json +0 -135
  26. package/components/icon/iconfont.ttf +0 -0
  27. package/components/icon/iconfont.woff +0 -0
  28. package/components/icon/iconfont.woff2 +0 -0
  29. package/components/layout/v-card/v-card.vue +0 -108
  30. package/components/layout/v-grid/v-grid.vue +0 -162
  31. package/components/layout/v-icon-grid/v-icon-grid.vue +0 -195
  32. package/components/layout/v-infinite-scroll/v-infinite-scroll.vue +0 -172
  33. package/components/layout/v-list/v-list.vue +0 -43
  34. package/components/layout/v-row/v-row.vue +0 -142
  35. package/components/layout/v-waterfall/v-waterfall.vue +0 -79
  36. package/components/model/compound/v-checkbox-group/v-checkbox-group.vue +0 -96
  37. package/components/model/compound/v-console/v-console.js +0 -20
  38. package/components/model/compound/v-console/v-console.vue +0 -299
  39. package/components/model/compound/v-date-time/v-date-time.vue +0 -261
  40. package/components/model/compound/v-dialog/v-dialog.vue +0 -178
  41. package/components/model/compound/v-drum-select-picker/v-drum-select-picker.vue +0 -83
  42. package/components/model/compound/v-form/v-form.vue +0 -226
  43. package/components/model/compound/v-form-item/v-form-item.vue +0 -255
  44. package/components/model/compound/v-image/v-image.vue +0 -357
  45. package/components/model/compound/v-input-desensitize/v-input-desensitize.vue +0 -101
  46. package/components/model/compound/v-page/v-page.vue +0 -11
  47. package/components/model/compound/v-pages/v-pages.vue +0 -141
  48. package/components/model/compound/v-picker-list/v-picker-list.vue +0 -109
  49. package/components/model/compound/v-popup/v-popup.vue +0 -151
  50. package/components/model/compound/v-radio-group/v-radio-group.vue +0 -86
  51. package/components/model/compound/v-select-picker/v-select-picker.vue +0 -202
  52. package/components/model/compound/v-series-picker-list/v-series-picker-list.vue +0 -221
  53. package/components/model/compound/v-series-select-picker/v-series-select-picker.vue +0 -203
  54. package/components/model/compound/v-switch/v-switch.vue +0 -136
  55. package/components/model/compound/v-tabs-page/v-tabs-page.vue +0 -138
  56. package/components/model/native/v-badge/v-badge.vue +0 -143
  57. package/components/model/native/v-button/v-button.vue +0 -81
  58. package/components/model/native/v-carousel/v-carousel.vue +0 -138
  59. package/components/model/native/v-checkbox/v-checkbox.vue +0 -215
  60. package/components/model/native/v-collapse/v-collapse.vue +0 -190
  61. package/components/model/native/v-header-navigation-bar/v-header-navigation-bar.vue +0 -92
  62. package/components/model/native/v-input/v-input.vue +0 -163
  63. package/components/model/native/v-input-code/v-input-code.vue +0 -146
  64. package/components/model/native/v-loading/v-loading.vue +0 -206
  65. package/components/model/native/v-menu/v-menu.vue +0 -222
  66. package/components/model/native/v-menu-slide/v-menu-slide.vue +0 -364
  67. package/components/model/native/v-min-loading/v-min-loading.vue +0 -80
  68. package/components/model/native/v-null/v-null.vue +0 -97
  69. package/components/model/native/v-overlay/v-overlay.vue +0 -96
  70. package/components/model/native/v-pull-up-refresh/v-pull-up-refresh.vue +0 -157
  71. package/components/model/native/v-radio/v-radio.vue +0 -138
  72. package/components/model/native/v-scroll-list/v-scroll-list.vue +0 -169
  73. package/components/model/native/v-steps/v-steps.vue +0 -253
  74. package/components/model/native/v-table/v-table.vue +0 -203
  75. package/components/model/native/v-tabs/v-tabs.vue +0 -235
  76. package/components/model/native/v-tag/v-tag.vue +0 -206
  77. package/components/model/native/v-text/v-text.vue +0 -187
  78. package/components/model/native/v-textarea/v-textarea.vue +0 -178
  79. package/components/model/native/v-title/v-title.vue +0 -91
  80. package/components/model/native/v-toast/info.png +0 -0
  81. package/components/model/native/v-toast/success.png +0 -0
  82. package/components/model/native/v-toast/v-toast.vue +0 -198
  83. package/components/model/native/v-toast/warn.png +0 -0
  84. package/components/model/native/v-upload-file-button/v-upload-file-button.vue +0 -296
  85. package/components/model/native/v-video/v-video.vue +0 -175
  86. package/components/model/native/v-window/v-window.vue +0 -158
  87. package/components/utils/event-modifiers.ts +0 -139
  88. package/components/utils/validator.ts +0 -451
  89. package/index.js +0 -372
@@ -1,139 +0,0 @@
1
- import { ref, onUnmounted } from 'vue';
2
-
3
- // ========== 类型定义 ==========
4
-
5
- type TimerHandle = ReturnType<typeof setTimeout>;
6
- type IntervalHandle = ReturnType<typeof setInterval>;
7
-
8
- export interface DebounceOptions {
9
- /** 防抖等待时间(毫秒) */
10
- wait: number;
11
- /** 是否立即执行第一次 */
12
- immediate?: boolean;
13
- }
14
-
15
- export interface CooldownOptions {
16
- /** 总冷却时间(毫秒) */
17
- stabilizationTime: number;
18
- /** 每次倒计时减少的值 */
19
- degressionTime: number;
20
- /** 倒计时更新间隔 */
21
- intervalUpdateTime: number;
22
- /** 是否在冷却期间点击时重置计时器 */
23
- resetOnClick?: boolean;
24
- /** 倒计时回调 */
25
- onCountdown?: (payload: { remaining: number; total: number }) => void;
26
- /** 冷却完成回调 */
27
- onComplete?: () => void;
28
- }
29
-
30
- // ========== 防抖 Hook ==========
31
-
32
- export function useDebounce<T extends (...args: any[]) => any>(callback: T, options: DebounceOptions) {
33
- const timer = ref<TimerHandle | null>(null);
34
- const isPending = ref(false);
35
-
36
- function debounce(...args: Parameters<T>) {
37
- if (timer.value) clearTimeout(timer.value);
38
-
39
- const shouldCallNow = options.immediate && !isPending.value;
40
-
41
- isPending.value = true;
42
- timer.value = setTimeout(() => {
43
- if (!options.immediate) {
44
- callback(...args);
45
- }
46
- isPending.value = false;
47
- }, options.wait);
48
-
49
- if (shouldCallNow) {
50
- callback(...args);
51
- }
52
- }
53
-
54
- function cancel() {
55
- if (timer.value) {
56
- clearTimeout(timer.value);
57
- timer.value = null;
58
- }
59
- isPending.value = false;
60
- }
61
-
62
- onUnmounted(() => {
63
- cancel();
64
- });
65
-
66
- return {
67
- debounce,
68
- cancel,
69
- isPending
70
- };
71
- }
72
-
73
- // ========== 冷却 Hook ==========
74
-
75
- export function useCooldown(options: CooldownOptions) {
76
- const countdownTimer = ref<IntervalHandle | null>(null);
77
- const cooldownTimer = ref<TimerHandle | null>(null);
78
- const countdown = ref(options.stabilizationTime);
79
- const isCountingDown = ref(false);
80
-
81
- function stop() {
82
- if (countdownTimer.value) {
83
- clearInterval(countdownTimer.value);
84
- countdownTimer.value = null;
85
- }
86
- if (cooldownTimer.value) {
87
- clearTimeout(cooldownTimer.value);
88
- cooldownTimer.value = null;
89
- }
90
- isCountingDown.value = false;
91
- }
92
-
93
- function start() {
94
- // 如果已在冷却中且允许重置,则重新开始
95
- if (isCountingDown.value && options.resetOnClick) {
96
- stop();
97
- } else if (isCountingDown.value) {
98
- return; // 冷却中且不允许重置,直接返回
99
- }
100
-
101
- isCountingDown.value = true;
102
- countdown.value = options.stabilizationTime;
103
-
104
- // 立即触发一次
105
- options.onCountdown?.({
106
- remaining: countdown.value,
107
- total: options.stabilizationTime
108
- });
109
-
110
- // 倒计时 interval
111
- countdownTimer.value = setInterval(() => {
112
- countdown.value -= options.degressionTime;
113
-
114
- const remaining = Math.max(0, countdown.value);
115
- options.onCountdown?.({ remaining, total: options.stabilizationTime });
116
-
117
- if (countdown.value <= 0) {
118
- stop();
119
- options.onComplete?.();
120
- }
121
- }, options.intervalUpdateTime);
122
-
123
- // 冷却结束定时器
124
- cooldownTimer.value = setTimeout(() => {
125
- isCountingDown.value = false;
126
- }, options.stabilizationTime);
127
- }
128
-
129
- onUnmounted(() => {
130
- stop();
131
- });
132
-
133
- return {
134
- countdown,
135
- isCountingDown,
136
- start,
137
- stop
138
- };
139
- }
@@ -1,451 +0,0 @@
1
- /**
2
- * 验证器工具
3
- * 提供常用数据验证函数
4
- */
5
-
6
- // ==================== 基础验证器 ====================
7
-
8
- /**
9
- * 创建枚举值验证器
10
- * 验证值是否在指定的枚举值列表中
11
- *
12
- * @param allowedValues 允许的值数组
13
- * @param errorMessage 错误提示信息(可选)
14
- * @returns 验证器函数
15
- */
16
- export function createEnumValidator<T extends string>(allowedValues: readonly T[], errorMessage?: string): (value: any) => value is T {
17
- const validator = (value: any): value is T => {
18
- const isValid = allowedValues.includes(value as T);
19
- if (!isValid && errorMessage) {
20
- console.warn(errorMessage, { value, allowedValues });
21
- }
22
- return isValid;
23
- };
24
-
25
- // 为验证器添加元数据
26
- validator.allowedValues = allowedValues;
27
- validator.errorMessage = errorMessage || `值必须在以下选项中: ${allowedValues.join(', ')}`;
28
-
29
- return validator;
30
- }
31
-
32
- /**
33
- * 创建数值范围验证器
34
- * 验证数值是否在指定范围内
35
- *
36
- * @param minimum 最小值
37
- * @param maximum 最大值
38
- * @param errorMessage 错误提示信息(可选)
39
- * @returns 验证器函数
40
- */
41
- export function createNumberRangeValidator(minimum: number, maximum: number, errorMessage?: string): (value: number) => boolean {
42
- const validator = (value: number): boolean => {
43
- const isValid = value >= minimum && value <= maximum;
44
- if (!isValid && errorMessage) {
45
- console.warn(errorMessage, { value, minimum, maximum });
46
- }
47
- return isValid;
48
- };
49
-
50
- validator.minimum = minimum;
51
- validator.maximum = maximum;
52
- validator.errorMessage = errorMessage || `数值必须在 ${minimum} 到 ${maximum} 之间`;
53
-
54
- return validator;
55
- }
56
-
57
- /**
58
- * 创建长度验证器
59
- * 验证字符串或数组的长度
60
- *
61
- * @param minimumLength 最小长度(可选)
62
- * @param maximumLength 最大长度(可选)
63
- * @param errorMessage 错误提示信息(可选)
64
- * @returns 验证器函数
65
- */
66
- export function createLengthValidator(minimumLength?: number, maximumLength?: number, errorMessage?: string): (value: string | any[]) => boolean {
67
- const validator = (value: string | any[]): boolean => {
68
- const length = value.length;
69
-
70
- if (minimumLength !== undefined && length < minimumLength) {
71
- if (errorMessage) console.warn(errorMessage, { length, minimumLength, maximumLength });
72
- return false;
73
- }
74
-
75
- if (maximumLength !== undefined && length > maximumLength) {
76
- if (errorMessage) console.warn(errorMessage, { length, minimumLength, maximumLength });
77
- return false;
78
- }
79
-
80
- return true;
81
- };
82
-
83
- validator.minimumLength = minimumLength;
84
- validator.maximumLength = maximumLength;
85
- validator.errorMessage = errorMessage || `长度必须在 ${minimumLength || '无限制'} 到 ${maximumLength || '无限制'} 之间`;
86
-
87
- return validator;
88
- }
89
-
90
- /**
91
- * 创建正则表达式验证器
92
- * 验证字符串是否匹配指定的正则表达式
93
- *
94
- * @param pattern 正则表达式
95
- * @param errorMessage 错误提示信息(可选)
96
- * @returns 验证器函数
97
- */
98
- export function createPatternValidator(pattern: RegExp, errorMessage?: string): (value: string) => boolean {
99
- const validator = (value: string): boolean => {
100
- const isValid = pattern.test(value);
101
- if (!isValid && errorMessage) {
102
- console.warn(errorMessage, { value, pattern });
103
- }
104
- return isValid;
105
- };
106
-
107
- validator.pattern = pattern;
108
- validator.errorMessage = errorMessage || `必须匹配正则表达式: ${pattern}`;
109
-
110
- return validator;
111
- }
112
-
113
- /**
114
- * 创建必填验证器
115
- * 验证值是否为非空
116
- *
117
- * @param errorMessage 错误提示信息(可选)
118
- * @returns 验证器函数
119
- */
120
- export function createRequiredValidator(errorMessage?: string): (value: any) => boolean {
121
- const validator = (value: any): boolean => {
122
- let isValid = false;
123
-
124
- if (value === undefined || value === null) {
125
- isValid = false;
126
- } else if (typeof value === 'string') {
127
- isValid = value.trim() !== '';
128
- } else if (Array.isArray(value)) {
129
- isValid = value.length > 0;
130
- } else if (typeof value === 'object') {
131
- isValid = Object.keys(value).length > 0;
132
- } else {
133
- isValid = true;
134
- }
135
-
136
- if (!isValid && errorMessage) {
137
- console.warn(errorMessage, { value });
138
- }
139
-
140
- return isValid;
141
- };
142
-
143
- validator.errorMessage = errorMessage || '此项为必填项';
144
-
145
- return validator;
146
- }
147
-
148
- // ==================== 特定格式验证器 ====================
149
-
150
- /**
151
- * 创建电子邮箱验证器
152
- * 验证电子邮箱格式
153
- *
154
- * @param errorMessage 错误提示信息(可选)
155
- * @returns 验证器函数
156
- */
157
- export function createEmailValidator(errorMessage?: string): (value: string) => boolean {
158
- const emailPattern = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/;
159
-
160
- const validator = (value: string): boolean => {
161
- const isValid = emailPattern.test(value);
162
- if (!isValid && errorMessage) {
163
- console.warn(errorMessage, { value });
164
- }
165
- return isValid;
166
- };
167
-
168
- validator.errorMessage = errorMessage || '请输入有效的电子邮箱地址';
169
-
170
- return validator;
171
- }
172
-
173
- /**
174
- * 创建手机号码验证器(中国大陆)
175
- * 验证中国大陆手机号码格式
176
- *
177
- * @param errorMessage 错误提示信息(可选)
178
- * @returns 验证器函数
179
- */
180
- export function createPhoneNumberValidator(errorMessage?: string): (value: string) => boolean {
181
- const phonePattern = /^1[3-9]\d{9}$/;
182
-
183
- const validator = (value: string): boolean => {
184
- const isValid = phonePattern.test(value);
185
- if (!isValid && errorMessage) {
186
- console.warn(errorMessage, { value });
187
- }
188
- return isValid;
189
- };
190
-
191
- validator.errorMessage = errorMessage || '请输入有效的手机号码(11位数字)';
192
-
193
- return validator;
194
- }
195
-
196
- /**
197
- * 创建URL地址验证器
198
- * 验证URL地址格式
199
- *
200
- * @param errorMessage 错误提示信息(可选)
201
- * @returns 验证器函数
202
- */
203
- export function createUrlValidator(errorMessage?: string): (value: string) => boolean {
204
- const urlPattern = /^(https?:\/\/)?([\da-z.-]+)\.([a-z.]{2,6})([/\w .-]*)*\/?$/;
205
-
206
- const validator = (value: string): boolean => {
207
- const isValid = urlPattern.test(value);
208
- if (!isValid && errorMessage) {
209
- console.warn(errorMessage, { value });
210
- }
211
- return isValid;
212
- };
213
-
214
- validator.errorMessage = errorMessage || '请输入有效的URL地址';
215
-
216
- return validator;
217
- }
218
-
219
- /**
220
- * 创建身份证号码验证器(中国大陆)
221
- * 验证中国大陆身份证号码格式
222
- *
223
- * @param errorMessage 错误提示信息(可选)
224
- * @returns 验证器函数
225
- */
226
- export function createIdCardValidator(errorMessage?: string): (value: string) => boolean {
227
- const idCardPattern = /^\d{17}[\dXx]$/;
228
-
229
- const validator = (value: string): boolean => {
230
- const isValid = idCardPattern.test(value);
231
- if (!isValid && errorMessage) {
232
- console.warn(errorMessage, { value });
233
- }
234
- return isValid;
235
- };
236
-
237
- validator.errorMessage = errorMessage || '请输入有效的身份证号码(18位)';
238
-
239
- return validator;
240
- }
241
-
242
- /**
243
- * 创建数值验证器
244
- * 验证数值类型和范围
245
- *
246
- * @param options 配置选项
247
- * @returns 验证器函数
248
- */
249
- export function createNumberValidator(options?: {
250
- minimum?: number;
251
- maximum?: number;
252
- integerOnly?: boolean;
253
- positiveOnly?: boolean;
254
- allowZero?: boolean;
255
- errorMessage?: string;
256
- }): (value: number) => boolean {
257
- const validator = (value: number): boolean => {
258
- // 检查是否为数值
259
- if (typeof value !== 'number' || isNaN(value)) {
260
- return false;
261
- }
262
-
263
- // 检查是否为整数
264
- if (options?.integerOnly && !Number.isInteger(value)) {
265
- return false;
266
- }
267
-
268
- // 检查是否为正数
269
- if (options?.positiveOnly && value <= 0) {
270
- return false;
271
- }
272
-
273
- // 检查是否允许零
274
- if (!options?.allowZero && value === 0) {
275
- return false;
276
- }
277
-
278
- // 检查最小值
279
- if (options?.minimum !== undefined && value < options.minimum) {
280
- return false;
281
- }
282
-
283
- // 检查最大值
284
- if (options?.maximum !== undefined && value > options.maximum) {
285
- return false;
286
- }
287
-
288
- return true;
289
- };
290
-
291
- validator.errorMessage = options?.errorMessage || '请输入有效的数值';
292
-
293
- return validator;
294
- }
295
-
296
- // ==================== 组合验证器 ====================
297
-
298
- /**
299
- * 创建组合验证器
300
- * 将多个验证器组合成一个验证器
301
- *
302
- * @param validators 验证器数组
303
- * @returns 验证器函数
304
- */
305
- export function createCombinedValidator<T>(...validators: ((value: T) => boolean)[]): (value: T) => boolean {
306
- const validator = (value: T): boolean => {
307
- for (const validatorFunc of validators) {
308
- if (!validatorFunc(value)) {
309
- return false;
310
- }
311
- }
312
- return true;
313
- };
314
-
315
- validator.validators = validators;
316
-
317
- return validator;
318
- }
319
-
320
- /**
321
- * 创建异步验证器
322
- * 用于需要异步验证的场景
323
- *
324
- * @param validator 验证器函数
325
- * @returns 异步验证器函数
326
- */
327
- export function createAsyncValidator<T>(validator: (value: T) => boolean | Promise<boolean>): (value: T) => Promise<boolean> {
328
- const asyncValidator = async (value: T): Promise<boolean> => {
329
- try {
330
- const result = validator(value);
331
- return result instanceof Promise ? await result : result;
332
- } catch (error) {
333
- console.error('验证器执行出错:', error);
334
- return false;
335
- }
336
- };
337
-
338
- return asyncValidator;
339
- }
340
-
341
- // ==================== 预定义验证器集合 ====================
342
-
343
- /**
344
- * 预定义验证器集合
345
- * 提供常用的验证器函数
346
- */
347
- export const Validators = {
348
- // 基础验证器
349
- enum: createEnumValidator,
350
- numberRange: createNumberRangeValidator,
351
- length: createLengthValidator,
352
- pattern: createPatternValidator,
353
- required: createRequiredValidator,
354
-
355
- // 格式验证器
356
- email: createEmailValidator,
357
- phoneNumber: createPhoneNumberValidator,
358
- url: createUrlValidator,
359
- idCard: createIdCardValidator,
360
- number: createNumberValidator,
361
-
362
- // 组合验证器
363
- combine: createCombinedValidator,
364
- async: createAsyncValidator,
365
-
366
- // 预定义验证规则
367
- // 正整数验证器
368
- positiveInteger: createNumberValidator({
369
- integerOnly: true,
370
- positiveOnly: true,
371
- allowZero: false,
372
- errorMessage: '请输入正整数'
373
- }),
374
-
375
- // 非负整数验证器
376
- nonNegativeInteger: createNumberValidator({
377
- integerOnly: true,
378
- positiveOnly: false,
379
- allowZero: true,
380
- errorMessage: '请输入非负整数'
381
- }),
382
-
383
- // 百分比验证器
384
- percentage: createNumberValidator({
385
- minimum: 0,
386
- maximum: 100,
387
- errorMessage: '请输入0到100之间的百分比数值'
388
- }),
389
-
390
- // 密码强度验证器(至少8位,包含字母和数字)
391
- passwordStrength: createCombinedValidator<string>(
392
- createLengthValidator(8, undefined, '密码长度至少8位'),
393
- createPatternValidator(/[a-zA-Z]/, '密码必须包含字母'),
394
- createPatternValidator(/[0-9]/, '密码必须包含数字')
395
- ),
396
-
397
- // 用户名验证器(只能包含字母、数字、下划线,3-20位)
398
- username: createCombinedValidator<string>(
399
- createLengthValidator(3, 20, '用户名长度必须在3到20位之间'),
400
- createPatternValidator(/^[a-zA-Z0-9_]+$/, '用户名只能包含字母、数字和下划线')
401
- )
402
- } as const;
403
-
404
- // ==================== 验证器工具函数 ====================
405
-
406
- /**
407
- * 验证值是否符合规则
408
- *
409
- * @param value 要验证的值
410
- * @param validator 验证器函数
411
- * @returns 验证结果
412
- */
413
- export function validateValue<T>(value: T, validator: (value: T) => boolean): { isValid: boolean; errorMessage?: string } {
414
- const isValid = validator(value);
415
-
416
- return {
417
- isValid,
418
- errorMessage: isValid ? undefined : (validator as any).errorMessage
419
- };
420
- }
421
-
422
- /**
423
- * 批量验证多个值
424
- *
425
- * @param values 值数组
426
- * @param validator 验证器函数
427
- * @returns 验证结果数组
428
- */
429
- export function validateValues<T>(values: T[], validator: (value: T) => boolean): Array<{ value: T; isValid: boolean; errorMessage?: string }> {
430
- return values.map((value) => ({
431
- value,
432
- ...validateValue(value, validator)
433
- }));
434
- }
435
-
436
- /**
437
- * 创建自定义错误消息的验证器
438
- *
439
- * @param validator 原始验证器
440
- * @param customErrorMessage 自定义错误消息
441
- * @returns 带自定义错误消息的验证器
442
- */
443
- export function withCustomErrorMessage<T>(validator: (value: T) => boolean, customErrorMessage: string): (value: T) => boolean {
444
- const customValidator = (value: T): boolean => {
445
- return validator(value);
446
- };
447
-
448
- customValidator.errorMessage = customErrorMessage;
449
-
450
- return customValidator;
451
- }