| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980 |
- <template>
- <el-input
- v-model="displayText"
- :placeholder="placeholder"
- :disabled="disabled"
- :clearable="clearable"
- style="width: 100%"
- @focus="handleFocus"
- @blur="handleBlur"
- @input="handleInput"
- />
- </template>
- <script setup lang="ts">
- import {
- formatMoneyDisplay,
- parseMoneyToNumber,
- sanitizeMoneyInput,
- } from '@/utils/money-format'
- defineOptions({ name: 'AmountInput' })
- interface Props {
- modelValue: number | null
- min?: number
- max?: number
- precision?: number
- placeholder?: string
- disabled?: boolean
- clearable?: boolean
- }
- const props = withDefaults(defineProps<Props>(), {
- min: undefined,
- max: undefined,
- precision: 2,
- placeholder: '',
- disabled: false,
- clearable: true,
- })
- const emit = defineEmits<{
- 'update:modelValue': [value: number | null]
- change: [value: number | null]
- }>()
- const displayText = ref('')
- const isFocused = ref(false)
- watch(
- () => props.modelValue,
- (val) => {
- if (!isFocused.value) {
- displayText.value = formatMoneyDisplay(val, props.precision)
- }
- },
- { immediate: true }
- )
- function handleFocus() {
- isFocused.value = true
- displayText.value = sanitizeMoneyInput(displayText.value, props.precision)
- }
- function handleInput(val: string) {
- displayText.value = sanitizeMoneyInput(val, props.precision)
- }
- function handleBlur() {
- isFocused.value = false
- let num = parseMoneyToNumber(displayText.value, props.precision)
- if (num !== null) {
- if (props.min !== undefined && num < props.min) num = props.min
- if (props.max !== undefined && num > props.max) num = props.max
- }
- emit('update:modelValue', num)
- emit('change', num)
- displayText.value = formatMoneyDisplay(num, props.precision)
- }
- </script>
|