Newer
Older
xc-business-system / src / components / precisionInputNumber / index.vue
<!-- 数字输入框 -->
<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>