<!-- 数字输入框 --> <script lang="ts" setup name="precisionInputNumber"> // ------------------定义props、 emit------------------- const props = defineProps({ // 数据绑定 modelValue: { type: [Number, String], default: '', }, // 输入 // 是否禁用 disabled: { type: Boolean, default: false, }, // 清空按钮 clearable: { type: Boolean, default: false, }, // 输入框最大长度 maxlength: { type: [Number, String], default: '', }, // 输入框最小长度 minlength: { type: [Number, String], default: '', }, // 是否显示统计字数 showWordLimit: { type: Boolean, default: false, }, placeholder: { type: String, default: '请输入', }, // 保留小数位数 precision: { type: Number, default: 0, }, max: { type: Number, default: 99999999, }, min: { type: Number, default: -99999999, }, valueOnClear: { type: Number, default: 0, }, // 失焦执行的方法(可传可不传) blur: { type: Function, default: () => {}, }, // 获取焦点执行的方法(可传可不传) focus: { type: Function, default: () => {}, }, // 输入框值变化执行的方法(可传可不传) change: { type: Function, default: () => {}, }, // 清空按钮时执行的方法(可传可不传) clear: { type: Function, default: () => {}, }, }) const emit = defineEmits(['update:modelValue', 'blur', 'change', 'focus']) const isFirst = ref(true) // -------------------------定义数据-------------------- const value = computed({ get() { return props.modelValue }, set(value) { emit('update:modelValue', value) }, }) watch(() => props.precision, (newVal) => { console.log('precision', newVal) }, { immediate: true, deep: true, }) // 输入框失焦 const handler = () => { console.log(props.precision, 'props.precision') const inputValue = value.value console.log(inputValue, '输入框的值') if (value.value === '' || value.value === null || value.value === undefined || isNaN(value.value)) { console.log(inputValue, '无效') if (props.valueOnClear) { if (Number(props.precision)) { value.value = Number(props.valueOnClear).toFixed(props.precision) } else { value.value = props.valueOnClear } } else { value.value = '' } return } if (Number(props.precision)) { value.value = Number(value.value || 0).toFixed(props.precision) } emit('blur', value.value) } const blur = () => { console.log('输入框失焦') handler() } // 输入框获取焦点 const focus = () => { console.log('输入框获取焦点') console.log(props.precision, 'props.precision') isFirst.value = false emit('focus', value.value) } // 输入框值变化 const change = () => { console.log('输入框值变化') emit('change', value.value) } // step步进 const step = computed(() => { if (props.precision) { console.log('步长', 0.1 * 10 ** -(props.precision - 1)) return 0.1 * 10 ** -(props.precision - 1) } else { return 1 } }) // -------------------------钩子-------------------- // 组件挂载的时候转换为科学计数法 watch(() => props.modelValue, (newVal) => { if (newVal) { if (!isFirst.value) { return } handler() isFirst.value = false } }) </script> <template> <el-input v-model.trim="value" type="number" resize="none" :disabled="props.disabled" :placeholder="props.placeholder" :clearable="props.clearable" :maxlength="props.maxlength" :minlength="props.minlength" :show-word-limit="props.showWordLimit" :max="props.max" :min="props.min" :step="step" style="width: 100%;" @blur="blur" @change="change" @focus="focus" @clear="props.clear" @mousewheel.prevent /> </template>