leisure-core 0.6.62 → 0.6.63
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.
- package/le-input-validate/src/main.vue +44 -81
- package/package.json +1 -1
|
@@ -30,57 +30,46 @@ export default {
|
|
|
30
30
|
inheritAttrs: false,
|
|
31
31
|
|
|
32
32
|
props: {
|
|
33
|
-
// 数值类型
|
|
34
33
|
number: {
|
|
35
34
|
type: Boolean,
|
|
36
35
|
default: false,
|
|
37
36
|
},
|
|
38
|
-
// 手机号类型
|
|
39
37
|
mobile: {
|
|
40
38
|
type: Boolean,
|
|
41
39
|
default: false,
|
|
42
40
|
},
|
|
43
|
-
// 邮箱类型
|
|
44
41
|
email: {
|
|
45
42
|
type: Boolean,
|
|
46
43
|
default: false,
|
|
47
44
|
},
|
|
48
|
-
// 金额类型
|
|
49
45
|
amount: {
|
|
50
46
|
type: Boolean,
|
|
51
47
|
default: false,
|
|
52
48
|
},
|
|
53
|
-
// 最大长度
|
|
54
49
|
maxlength: {
|
|
55
50
|
type: [Number, String],
|
|
56
51
|
default: null,
|
|
57
52
|
},
|
|
58
|
-
// 是否显示字数统计
|
|
59
53
|
showCount: {
|
|
60
54
|
type: Boolean,
|
|
61
55
|
default: false,
|
|
62
56
|
},
|
|
63
|
-
// 自定义验证函数
|
|
64
57
|
validator: {
|
|
65
58
|
type: Function,
|
|
66
59
|
default: null,
|
|
67
60
|
},
|
|
68
|
-
// 值
|
|
69
61
|
value: {
|
|
70
62
|
type: [String, Number],
|
|
71
63
|
default: "",
|
|
72
64
|
},
|
|
73
|
-
// 是否允许小数
|
|
74
65
|
allowDecimal: {
|
|
75
66
|
type: Boolean,
|
|
76
67
|
default: true,
|
|
77
68
|
},
|
|
78
|
-
// 小数位数限制
|
|
79
69
|
decimalLimit: {
|
|
80
70
|
type: Number,
|
|
81
71
|
default: 2,
|
|
82
72
|
},
|
|
83
|
-
// 新增:是否允许负数(仅对 number 和 amount 类型生效)
|
|
84
73
|
allowNegative: {
|
|
85
74
|
type: Boolean,
|
|
86
75
|
default: false,
|
|
@@ -101,11 +90,8 @@ export default {
|
|
|
101
90
|
mergedAttrs() {
|
|
102
91
|
const attrs = { ...this.$attrs };
|
|
103
92
|
|
|
104
|
-
// 移除已单独处理的属性
|
|
105
93
|
delete attrs.class;
|
|
106
94
|
delete attrs.style;
|
|
107
|
-
|
|
108
|
-
// 移除props中定义的属性,避免重复
|
|
109
95
|
delete attrs.number;
|
|
110
96
|
delete attrs.mobile;
|
|
111
97
|
delete attrs.email;
|
|
@@ -116,9 +102,8 @@ export default {
|
|
|
116
102
|
delete attrs.value;
|
|
117
103
|
delete attrs.allowDecimal;
|
|
118
104
|
delete attrs.decimalLimit;
|
|
119
|
-
delete attrs.allowNegative;
|
|
105
|
+
delete attrs.allowNegative;
|
|
120
106
|
|
|
121
|
-
// 合并值,确保我们的 value 逻辑优先
|
|
122
107
|
return {
|
|
123
108
|
...attrs,
|
|
124
109
|
value: this.displayValue,
|
|
@@ -130,7 +115,6 @@ export default {
|
|
|
130
115
|
if (this.maxlength) {
|
|
131
116
|
return Number(this.maxlength);
|
|
132
117
|
}
|
|
133
|
-
// 手机号默认11位
|
|
134
118
|
if (this.mobile) {
|
|
135
119
|
return 11;
|
|
136
120
|
}
|
|
@@ -148,7 +132,6 @@ export default {
|
|
|
148
132
|
},
|
|
149
133
|
|
|
150
134
|
displayValue() {
|
|
151
|
-
// 金额类型在非聚焦状态下显示格式化后的值
|
|
152
135
|
if (
|
|
153
136
|
this.amount &&
|
|
154
137
|
!this.isFocused &&
|
|
@@ -168,7 +151,6 @@ export default {
|
|
|
168
151
|
|
|
169
152
|
internalValue(newVal) {
|
|
170
153
|
this.validateInput(newVal);
|
|
171
|
-
// 触发外部监听的事件
|
|
172
154
|
this.$listeners.change && this.$listeners.change(newVal);
|
|
173
155
|
},
|
|
174
156
|
},
|
|
@@ -177,22 +159,18 @@ export default {
|
|
|
177
159
|
handleInput(value) {
|
|
178
160
|
let processedValue = value;
|
|
179
161
|
|
|
180
|
-
// 数值类型处理
|
|
181
162
|
if (this.number) {
|
|
182
163
|
processedValue = this.formatNumber(value);
|
|
183
164
|
}
|
|
184
165
|
|
|
185
|
-
// 手机号类型处理
|
|
186
166
|
if (this.mobile) {
|
|
187
167
|
processedValue = this.formatMobile(value);
|
|
188
168
|
}
|
|
189
169
|
|
|
190
|
-
// 金额类型处理
|
|
191
170
|
if (this.amount) {
|
|
192
171
|
processedValue = this.formatAmountInput(value);
|
|
193
172
|
}
|
|
194
173
|
|
|
195
|
-
// 长度限制
|
|
196
174
|
if (
|
|
197
175
|
this.computedMaxlength &&
|
|
198
176
|
processedValue.length > this.computedMaxlength
|
|
@@ -202,8 +180,6 @@ export default {
|
|
|
202
180
|
|
|
203
181
|
this.internalValue = processedValue;
|
|
204
182
|
this.$emit("input", processedValue);
|
|
205
|
-
|
|
206
|
-
// 触发外部监听的事件
|
|
207
183
|
this.$listeners.input && this.$listeners.input(processedValue);
|
|
208
184
|
},
|
|
209
185
|
|
|
@@ -212,16 +188,12 @@ export default {
|
|
|
212
188
|
this.isFocused = false;
|
|
213
189
|
this.validateInput(this.internalValue, true);
|
|
214
190
|
this.$emit("blur", event);
|
|
215
|
-
|
|
216
|
-
// 触发外部监听的事件
|
|
217
191
|
this.$listeners.blur && this.$listeners.blur(event);
|
|
218
192
|
},
|
|
219
193
|
|
|
220
194
|
handleFocus(event) {
|
|
221
195
|
this.isFocused = true;
|
|
222
196
|
this.$emit("focus", event);
|
|
223
|
-
|
|
224
|
-
// 触发外部监听的事件
|
|
225
197
|
this.$listeners.focus && this.$listeners.focus(event);
|
|
226
198
|
},
|
|
227
199
|
|
|
@@ -229,37 +201,29 @@ export default {
|
|
|
229
201
|
this.hasError = false;
|
|
230
202
|
this.errorMessage = "";
|
|
231
203
|
this.$emit("clear");
|
|
232
|
-
|
|
233
|
-
// 触发外部监听的事件
|
|
234
204
|
this.$listeners.clear && this.$listeners.clear();
|
|
235
205
|
},
|
|
236
206
|
|
|
237
207
|
formatNumber(value) {
|
|
238
|
-
// 根据 allowNegative 决定是否保留负号
|
|
239
208
|
let filtered = value;
|
|
240
209
|
if (this.allowNegative) {
|
|
241
|
-
//
|
|
210
|
+
// 允许负数:保留数字、小数点、负号,负号只能出现在开头
|
|
242
211
|
filtered = value.replace(/[^\d.-]/g, "");
|
|
243
|
-
// 处理多个负号的情况:只保留第一个负号,并确保负号在开头
|
|
244
212
|
const hasNegative = filtered.startsWith("-");
|
|
245
213
|
filtered = filtered.replace(/-/g, "");
|
|
246
214
|
if (hasNegative) {
|
|
247
215
|
filtered = "-" + filtered;
|
|
248
216
|
}
|
|
249
|
-
// 处理小数点后多余的小数点
|
|
250
217
|
filtered = filtered.replace(/(\..*)\./g, "$1");
|
|
251
218
|
} else {
|
|
252
|
-
// 不允许负数:直接过滤掉负号
|
|
253
219
|
filtered = value.replace(/[^\d.]/g, "");
|
|
254
220
|
filtered = filtered.replace(/(\..*)\./g, "$1");
|
|
255
221
|
}
|
|
256
222
|
|
|
257
|
-
// 如果不允许小数,移除小数点
|
|
258
223
|
if (this.number && !this.allowDecimal) {
|
|
259
224
|
filtered = filtered.replace(/\./g, "");
|
|
260
225
|
}
|
|
261
226
|
|
|
262
|
-
// 如果允许小数,限制小数位数
|
|
263
227
|
if (this.number && this.allowDecimal && this.decimalLimit > 0) {
|
|
264
228
|
const parts = filtered.split(".");
|
|
265
229
|
if (parts.length === 2 && parts[1].length > this.decimalLimit) {
|
|
@@ -271,69 +235,62 @@ export default {
|
|
|
271
235
|
},
|
|
272
236
|
|
|
273
237
|
formatMobile(value) {
|
|
274
|
-
// 只允许数字
|
|
275
238
|
return value.replace(/\D/g, "");
|
|
276
239
|
},
|
|
277
240
|
|
|
278
241
|
formatAmountInput(value) {
|
|
279
|
-
// 金额输入过滤
|
|
280
242
|
let filteredValue = value;
|
|
281
243
|
|
|
282
244
|
if (this.allowNegative) {
|
|
283
|
-
// 允许负数:保留数字、小数点、负号,负号只能出现在开头
|
|
284
245
|
filteredValue = value.replace(/[^\d.-]/g, "");
|
|
285
246
|
const hasNegative = filteredValue.startsWith("-");
|
|
286
247
|
filteredValue = filteredValue.replace(/-/g, "");
|
|
287
248
|
if (hasNegative) {
|
|
288
249
|
filteredValue = "-" + filteredValue;
|
|
289
250
|
}
|
|
251
|
+
// 修复:允许临时输入 '-' 或 '-.',不清空,以便用户继续输入小数部分
|
|
252
|
+
if (filteredValue === "-" || filteredValue === "-.") {
|
|
253
|
+
return filteredValue;
|
|
254
|
+
}
|
|
290
255
|
} else {
|
|
291
|
-
// 不允许负数:只保留数字和小数点
|
|
292
256
|
filteredValue = value.replace(/[^\d.]/g, "");
|
|
293
257
|
}
|
|
294
258
|
|
|
295
|
-
// 如果禁止小数,则删除所有小数点
|
|
296
259
|
if (!this.allowDecimal) {
|
|
297
260
|
return filteredValue.replace(/\./g, "");
|
|
298
261
|
}
|
|
299
262
|
|
|
300
|
-
// 处理多个小数点的情况
|
|
301
263
|
const parts = filteredValue.split(".");
|
|
302
264
|
if (parts.length > 2) {
|
|
303
265
|
filteredValue = parts[0] + "." + parts.slice(1).join("");
|
|
304
266
|
}
|
|
305
267
|
|
|
306
|
-
// 限制小数位数
|
|
307
268
|
if (parts.length === 2 && parts[1].length > this.decimalLimit) {
|
|
308
269
|
filteredValue =
|
|
309
270
|
parts[0] + "." + parts[1].substring(0, this.decimalLimit);
|
|
310
271
|
}
|
|
311
272
|
|
|
312
|
-
// 特殊情况:单独的负号或负号+小数点不允许,清除无效输入
|
|
313
|
-
if (filteredValue === "-" || filteredValue === "-.") {
|
|
314
|
-
filteredValue = "";
|
|
315
|
-
}
|
|
316
|
-
|
|
317
273
|
return filteredValue;
|
|
318
274
|
},
|
|
319
275
|
|
|
320
276
|
formatAmount(value) {
|
|
321
277
|
if (value === undefined || value === null || value === "") return "";
|
|
322
278
|
|
|
323
|
-
// 将值转换为字符串,处理负数
|
|
324
279
|
const strValue = String(value);
|
|
325
280
|
const isNegative = strValue.startsWith("-");
|
|
326
281
|
let absValue = isNegative ? strValue.slice(1) : strValue;
|
|
327
282
|
|
|
328
|
-
//
|
|
283
|
+
// 修复:处理无效的中间状态,如 '-' 或 '-.'
|
|
284
|
+
if (absValue === "" || absValue === ".") {
|
|
285
|
+
return strValue;
|
|
286
|
+
}
|
|
287
|
+
|
|
329
288
|
const parts = absValue.split(".");
|
|
330
289
|
let integerPart = parts[0];
|
|
331
290
|
let decimalPart = parts.length > 1 ? parts[1] : "";
|
|
332
291
|
|
|
333
|
-
// 对整数部分添加千分位分隔符
|
|
334
292
|
integerPart = integerPart.replace(/\B(?=(\d{3})+(?!\d))/g, ",");
|
|
335
293
|
|
|
336
|
-
// 组合整数和小数部分
|
|
337
294
|
let formatted = "";
|
|
338
295
|
if (decimalPart && this.allowDecimal) {
|
|
339
296
|
formatted = `${integerPart}.${decimalPart}`;
|
|
@@ -341,7 +298,6 @@ export default {
|
|
|
341
298
|
formatted = integerPart;
|
|
342
299
|
}
|
|
343
300
|
|
|
344
|
-
// 添加负号
|
|
345
301
|
if (isNegative && formatted !== "") {
|
|
346
302
|
formatted = "-" + formatted;
|
|
347
303
|
}
|
|
@@ -354,15 +310,12 @@ export default {
|
|
|
354
310
|
|
|
355
311
|
let isValid = true;
|
|
356
312
|
let message = "";
|
|
357
|
-
|
|
358
313
|
const strValue = String(value || "");
|
|
359
314
|
|
|
360
|
-
// 数值验证
|
|
361
315
|
if (this.number && strValue) {
|
|
362
316
|
let numberPattern;
|
|
363
317
|
if (this.allowNegative) {
|
|
364
|
-
|
|
365
|
-
numberPattern = new RegExp(`^-?\\d*\\.?\\d*$`);
|
|
318
|
+
numberPattern = /^-?\d*\.?\d*$/;
|
|
366
319
|
} else {
|
|
367
320
|
numberPattern = /^\d*\.?\d*$/;
|
|
368
321
|
}
|
|
@@ -372,7 +325,6 @@ export default {
|
|
|
372
325
|
}
|
|
373
326
|
}
|
|
374
327
|
|
|
375
|
-
// 手机号验证
|
|
376
328
|
if (this.mobile && strValue) {
|
|
377
329
|
if (!/^1[3-9]\d{9}$/.test(strValue)) {
|
|
378
330
|
isValid = false;
|
|
@@ -380,7 +332,6 @@ export default {
|
|
|
380
332
|
}
|
|
381
333
|
}
|
|
382
334
|
|
|
383
|
-
// 邮箱验证
|
|
384
335
|
if (this.email && strValue) {
|
|
385
336
|
if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(strValue)) {
|
|
386
337
|
isValid = false;
|
|
@@ -388,40 +339,56 @@ export default {
|
|
|
388
339
|
}
|
|
389
340
|
}
|
|
390
341
|
|
|
391
|
-
// 金额验证
|
|
392
342
|
if (this.amount && strValue) {
|
|
393
|
-
// 去除千分位分隔符后再验证
|
|
394
343
|
const cleanValue = strValue.replace(/,/g, "");
|
|
395
344
|
let amountPattern;
|
|
396
345
|
if (this.allowNegative) {
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
346
|
+
// 更严格的金额正则:不允许单独的负号、小数点、负号+小数点
|
|
347
|
+
if (this.allowDecimal) {
|
|
348
|
+
amountPattern = /^-?(?:[1-9]\d*|0)(?:\.\d{0,2})?$|^-?0\.\d{0,2}$/;
|
|
349
|
+
} else {
|
|
350
|
+
amountPattern = /^-?(?:[1-9]\d*|0)$/;
|
|
351
|
+
}
|
|
352
|
+
// 临时允许用户输入过程中的不完整状态,但最终提交时需完整
|
|
353
|
+
// 这里先检查完整格式,如果是不完整状态(如 '-'、'-.'、'.')也认为无效
|
|
354
|
+
if (
|
|
355
|
+
cleanValue === "-" ||
|
|
356
|
+
cleanValue === "-." ||
|
|
357
|
+
cleanValue === "." ||
|
|
358
|
+
cleanValue === ""
|
|
359
|
+
) {
|
|
360
|
+
isValid = false;
|
|
361
|
+
message = this.allowDecimal
|
|
362
|
+
? "请输入有效的金额"
|
|
363
|
+
: "请输入有效的整数金额";
|
|
364
|
+
} else if (!amountPattern.test(cleanValue)) {
|
|
365
|
+
isValid = false;
|
|
366
|
+
message = this.allowDecimal
|
|
367
|
+
? `请输入有效的金额(最多${this.decimalLimit}位小数)`
|
|
368
|
+
: "请输入有效的金额(整数)";
|
|
369
|
+
}
|
|
400
370
|
} else {
|
|
401
371
|
amountPattern = this.allowDecimal
|
|
402
|
-
?
|
|
403
|
-
:
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
372
|
+
? /^(?:[1-9]\d*|0)(?:\.\d{0,2})?$|^0\.\d{0,2}$/
|
|
373
|
+
: /^(?:[1-9]\d*|0)$/;
|
|
374
|
+
if (!amountPattern.test(cleanValue)) {
|
|
375
|
+
isValid = false;
|
|
376
|
+
message = this.allowDecimal
|
|
377
|
+
? `请输入有效的金额(最多${this.decimalLimit}位小数)`
|
|
378
|
+
: "请输入有效的金额(整数)";
|
|
379
|
+
}
|
|
410
380
|
}
|
|
411
|
-
// 额外检查负数是否允许
|
|
412
381
|
if (!this.allowNegative && cleanValue.startsWith("-")) {
|
|
413
382
|
isValid = false;
|
|
414
383
|
message = "不允许输入负数";
|
|
415
384
|
}
|
|
416
385
|
}
|
|
417
386
|
|
|
418
|
-
// 最大长度验证
|
|
419
387
|
if (this.computedMaxlength && strValue.length > this.computedMaxlength) {
|
|
420
388
|
isValid = false;
|
|
421
389
|
message = `输入内容不能超过${this.computedMaxlength}个字符`;
|
|
422
390
|
}
|
|
423
391
|
|
|
424
|
-
// 自定义验证
|
|
425
392
|
if (this.validator && typeof this.validator === "function") {
|
|
426
393
|
const customResult = this.validator(value);
|
|
427
394
|
if (customResult !== true) {
|
|
@@ -436,25 +403,21 @@ export default {
|
|
|
436
403
|
return isValid;
|
|
437
404
|
},
|
|
438
405
|
|
|
439
|
-
// 公开方法:手动验证
|
|
440
406
|
validate() {
|
|
441
407
|
this.isTouched = true;
|
|
442
408
|
return this.validateInput(this.internalValue, true);
|
|
443
409
|
},
|
|
444
410
|
|
|
445
|
-
// 公开方法:清除验证状态
|
|
446
411
|
clearValidate() {
|
|
447
412
|
this.hasError = false;
|
|
448
413
|
this.errorMessage = "";
|
|
449
414
|
this.isTouched = false;
|
|
450
415
|
},
|
|
451
416
|
|
|
452
|
-
// 公开方法:聚焦输入框
|
|
453
417
|
focus() {
|
|
454
418
|
this.$refs.inputRef?.focus();
|
|
455
419
|
},
|
|
456
420
|
|
|
457
|
-
// 公开方法:失焦输入框
|
|
458
421
|
blur() {
|
|
459
422
|
this.$refs.inputRef?.blur();
|
|
460
423
|
},
|