@aspire-ui/element-component-pro 1.0.8 → 1.0.10
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/dist/ProForm/FormattedNumberInput.vue.d.ts +13 -0
- package/dist/element-component-pro.es.js +557 -525
- package/dist/element-component-pro.es.js.map +1 -1
- package/dist/element-component-pro.umd.js +2 -2
- package/dist/element-component-pro.umd.js.map +1 -1
- package/dist/index.d.ts +9 -0
- package/dist/utils/formattedNumber.d.ts +9 -0
- package/package.json +1 -1
- package/src/ProForm/FormattedNumberInput.vue +19 -3
- package/src/utils/formattedNumber.ts +42 -0
package/dist/index.d.ts
CHANGED
|
@@ -2594,6 +2594,10 @@ declare const _default: {
|
|
|
2594
2594
|
type: import('vue').PropType<import('.').FormattedNumberRounding>;
|
|
2595
2595
|
default: string;
|
|
2596
2596
|
};
|
|
2597
|
+
inputLimit: {
|
|
2598
|
+
type: import('vue').PropType<boolean>;
|
|
2599
|
+
default: boolean;
|
|
2600
|
+
};
|
|
2597
2601
|
}, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {
|
|
2598
2602
|
input: (value: unknown) => void;
|
|
2599
2603
|
}, string, Readonly<import('vue').ExtractPropTypes<{
|
|
@@ -2618,10 +2622,15 @@ declare const _default: {
|
|
|
2618
2622
|
type: import('vue').PropType<import('.').FormattedNumberRounding>;
|
|
2619
2623
|
default: string;
|
|
2620
2624
|
};
|
|
2625
|
+
inputLimit: {
|
|
2626
|
+
type: import('vue').PropType<boolean>;
|
|
2627
|
+
default: boolean;
|
|
2628
|
+
};
|
|
2621
2629
|
}>>, {
|
|
2622
2630
|
integerDigits: number;
|
|
2623
2631
|
decimalPlaces: number;
|
|
2624
2632
|
rounding: import('.').FormattedNumberRounding;
|
|
2633
|
+
inputLimit: boolean;
|
|
2625
2634
|
}>;
|
|
2626
2635
|
};
|
|
2627
2636
|
export default _default;
|
|
@@ -3,6 +3,11 @@ export type FormattedNumberRounding = 'floor' | 'ceil' | 'round';
|
|
|
3
3
|
/** 仅保留数字、至多一个小数点、可选前导负号 */
|
|
4
4
|
export declare function sanitizeNumericInput(raw: string): string;
|
|
5
5
|
export declare function stripNumberGrouping(s: string): string;
|
|
6
|
+
/**
|
|
7
|
+
* 对已清洗的数字串按整数位、小数位截断输入长度(inputLimit 为 true 时使用)。
|
|
8
|
+
* 整数部分至多 integerDigits 位,小数部分至多 decimalPlaces 位;保留末尾仅小数点(如 `12.`)以便继续输入。
|
|
9
|
+
*/
|
|
10
|
+
export declare function applyNumericInputDigitLimits(sanitized: string, integerDigits: number, decimalPlaces: number): string;
|
|
6
11
|
/** 按整数位数上限约束绝对值 */
|
|
7
12
|
export declare function clampByIntegerDigits(value: number, integerDigits: number, decimalPlaces: number): number;
|
|
8
13
|
export declare function roundToDecimals(value: number, decimalPlaces: number, rounding: FormattedNumberRounding): number;
|
|
@@ -10,6 +15,10 @@ export declare function roundToDecimals(value: number, decimalPlaces: number, ro
|
|
|
10
15
|
* 解析 → 按整数位夹紧 → 按小数位与进位方式舍入 → 再夹紧(防止舍入后越界)
|
|
11
16
|
*/
|
|
12
17
|
export declare function normalizeNumericValue(value: number, integerDigits: number, decimalPlaces: number, rounding: FormattedNumberRounding): number;
|
|
18
|
+
/**
|
|
19
|
+
* 固定小数位数字符串(无千分位),用于表单存值以保留配置的小数位数(number 无法保留尾随 0)。
|
|
20
|
+
*/
|
|
21
|
+
export declare function toFixedDecimalString(value: number, decimalPlaces: number): string;
|
|
13
22
|
/** 千分位格式化展示(整数部分),小数部分固定 m 位 */
|
|
14
23
|
export declare function formatWithThousands(value: number, decimalPlaces: number): string;
|
|
15
24
|
/** 编辑态:无千分位,去掉多余尾部 0(在 m 位精度内) */
|
package/package.json
CHANGED
|
@@ -14,11 +14,13 @@
|
|
|
14
14
|
import { ref, watch } from 'vue'
|
|
15
15
|
import type { FormattedNumberRounding } from '../utils/formattedNumber'
|
|
16
16
|
import {
|
|
17
|
+
applyNumericInputDigitLimits,
|
|
17
18
|
formatWithThousands,
|
|
18
19
|
normalizeNumericValue,
|
|
19
20
|
numberToEditString,
|
|
20
21
|
sanitizeNumericInput,
|
|
21
22
|
stripNumberGrouping,
|
|
23
|
+
toFixedDecimalString,
|
|
22
24
|
} from '../utils/formattedNumber'
|
|
23
25
|
|
|
24
26
|
const props = withDefaults(
|
|
@@ -32,11 +34,17 @@ const props = withDefaults(
|
|
|
32
34
|
decimalPlaces?: number
|
|
33
35
|
/** 进位方式,默认四舍五入 */
|
|
34
36
|
rounding?: FormattedNumberRounding
|
|
37
|
+
/**
|
|
38
|
+
* 为 true 时在输入过程中按 integerDigits / decimalPlaces 限制可输入位数;
|
|
39
|
+
* 为 false 时仅失焦后规范化,输入阶段不截断长度。
|
|
40
|
+
*/
|
|
41
|
+
inputLimit?: boolean
|
|
35
42
|
}>(),
|
|
36
43
|
{
|
|
37
44
|
integerDigits: 5,
|
|
38
45
|
decimalPlaces: 6,
|
|
39
46
|
rounding: 'round',
|
|
47
|
+
inputLimit: true,
|
|
40
48
|
}
|
|
41
49
|
)
|
|
42
50
|
|
|
@@ -78,13 +86,21 @@ watch(
|
|
|
78
86
|
{ immediate: true, deep: true }
|
|
79
87
|
)
|
|
80
88
|
|
|
89
|
+
function emitStoredValue(normalized: number) {
|
|
90
|
+
emit('input', toFixedDecimalString(normalized, decM()))
|
|
91
|
+
}
|
|
92
|
+
|
|
81
93
|
function onInput(val: string) {
|
|
82
|
-
|
|
94
|
+
let clean = sanitizeNumericInput(val)
|
|
95
|
+
if (props.inputLimit !== false) {
|
|
96
|
+
clean = applyNumericInputDigitLimits(clean, intN(), decM())
|
|
97
|
+
}
|
|
83
98
|
displayText.value = clean
|
|
84
99
|
if (clean === '' || clean === '-') return
|
|
85
100
|
const num = Number(clean)
|
|
86
101
|
if (!Number.isFinite(num)) return
|
|
87
|
-
|
|
102
|
+
const normalized = normalizeNumericValue(num, intN(), decM(), props.rounding)
|
|
103
|
+
emitStoredValue(normalized)
|
|
88
104
|
}
|
|
89
105
|
|
|
90
106
|
function onFocus() {
|
|
@@ -117,6 +133,6 @@ function onBlur() {
|
|
|
117
133
|
}
|
|
118
134
|
const final = normalizeNumericValue(parsed, intN(), decM(), props.rounding)
|
|
119
135
|
displayText.value = formatWithThousands(final, decM())
|
|
120
|
-
|
|
136
|
+
emitStoredValue(final)
|
|
121
137
|
}
|
|
122
138
|
</script>
|
|
@@ -31,6 +31,40 @@ export function stripNumberGrouping(s: string): string {
|
|
|
31
31
|
return s.replace(/,/g, '').trim()
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
+
/**
|
|
35
|
+
* 对已清洗的数字串按整数位、小数位截断输入长度(inputLimit 为 true 时使用)。
|
|
36
|
+
* 整数部分至多 integerDigits 位,小数部分至多 decimalPlaces 位;保留末尾仅小数点(如 `12.`)以便继续输入。
|
|
37
|
+
*/
|
|
38
|
+
export function applyNumericInputDigitLimits(
|
|
39
|
+
sanitized: string,
|
|
40
|
+
integerDigits: number,
|
|
41
|
+
decimalPlaces: number
|
|
42
|
+
): string {
|
|
43
|
+
if (!sanitized || sanitized === '-') return sanitized
|
|
44
|
+
const neg = sanitized[0] === '-'
|
|
45
|
+
let body = neg ? sanitized.slice(1) : sanitized
|
|
46
|
+
const dotIdx = body.indexOf('.')
|
|
47
|
+
if (dotIdx === -1) {
|
|
48
|
+
const maxInt = Math.max(0, integerDigits)
|
|
49
|
+
body = maxInt > 0 ? body.slice(0, maxInt) : body
|
|
50
|
+
return neg ? '-' + body : body
|
|
51
|
+
}
|
|
52
|
+
let intPart = body.slice(0, dotIdx)
|
|
53
|
+
if (integerDigits > 0) {
|
|
54
|
+
intPart = intPart.slice(0, integerDigits)
|
|
55
|
+
}
|
|
56
|
+
const afterDot = body.slice(dotIdx + 1)
|
|
57
|
+
const endsWithDot = afterDot === '' && body.endsWith('.')
|
|
58
|
+
if (decimalPlaces <= 0) {
|
|
59
|
+
return neg ? '-' + intPart : intPart
|
|
60
|
+
}
|
|
61
|
+
if (endsWithDot) {
|
|
62
|
+
return (neg ? '-' : '') + intPart + '.'
|
|
63
|
+
}
|
|
64
|
+
const decPart = afterDot.slice(0, decimalPlaces)
|
|
65
|
+
return (neg ? '-' : '') + intPart + '.' + decPart
|
|
66
|
+
}
|
|
67
|
+
|
|
34
68
|
function maxAbsValue(integerDigits: number, decimalPlaces: number): number {
|
|
35
69
|
const maxInt = Math.pow(10, integerDigits) - 1
|
|
36
70
|
if (decimalPlaces <= 0) return maxInt
|
|
@@ -96,6 +130,14 @@ export function normalizeNumericValue(
|
|
|
96
130
|
return v
|
|
97
131
|
}
|
|
98
132
|
|
|
133
|
+
/**
|
|
134
|
+
* 固定小数位数字符串(无千分位),用于表单存值以保留配置的小数位数(number 无法保留尾随 0)。
|
|
135
|
+
*/
|
|
136
|
+
export function toFixedDecimalString(value: number, decimalPlaces: number): string {
|
|
137
|
+
if (Number.isNaN(value) || !Number.isFinite(value)) return ''
|
|
138
|
+
return value.toFixed(Math.max(0, decimalPlaces))
|
|
139
|
+
}
|
|
140
|
+
|
|
99
141
|
/** 千分位格式化展示(整数部分),小数部分固定 m 位 */
|
|
100
142
|
export function formatWithThousands(value: number, decimalPlaces: number): string {
|
|
101
143
|
if (Number.isNaN(value) || !Number.isFinite(value)) return ''
|