wupengfei
2025-02-12 2d4a6ebe75599eaa51d5fb0f522dc9fa6825af00
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
<template>
  <nut-input type="number" :formatter="formatter" formatTrigger="onBlur">
    <template #right>
      <slot name="right"></slot>
    </template>
  </nut-input>
</template>
 
<script setup lang="ts">
defineOptions({
  name: 'NumberInput',
});
 
type Props = {
  min?: number;
  max?: number;
  precision?: number;
};
 
const props = withDefaults(defineProps<Props>(), {
  max: Math.pow(2, 53) - 1,
});
 
function formatter(value: string): string {
  const newVal = value !== '' ? Number.parseFloat(value) : '';
  if (Number.isNaN(newVal)) {
    return '';
  }
  if (newVal && newVal > props.max) {
    return `${toPrecision(props.max)}`;
  }
  if (props.min !== undefined && newVal && newVal < props.min) {
    return `${toPrecision(props.min)}`;
  }
  return newVal !== '' ? `${toPrecision(newVal)}` : newVal;
}
 
function toPrecision(num: number) {
  if (props.precision) {
    if (props.precision === 0) return Math.round(num);
    let snum = String(num);
    const pointPos = snum.indexOf('.');
    if (pointPos === -1) return num;
    const nums = snum.replace('.', '').split('');
    const datum = nums[pointPos + props.precision];
    if (!datum) return num;
    const length = snum.length;
    if (snum.charAt(length - 1) === '5') {
      snum = `${snum.slice(0, Math.max(0, length - 1))}6`;
    }
    return Number(snum).toFixed(props.precision);
  }
  return String(num);
}
</script>