封装金额组件与利率组件

88 阅读1分钟

需求来了

前两日,Leader 找到我,说咱们项目中大量涉及到金额和利率的地方,要求我:

  1. 封装一个金额组件,只能输入数字,并且有两种情况:第一只能输入非负数,不限制小数点保留位数;第二种只能输入正整数,没有小数。
  2. 封装一个利率组件,只能输入大于0并且小于等于100的数字,并且限制最多保留两位数;

我说,那好,我试试!

封装金额组件

@/components/AmountInput.vue

<template>
  <div class="amount-input">
    <el-input
      v-model="value"
      @input="input"
      @change="change"
      clearable
    ></el-input>
  </div>
</template>
<script>
export default {
  name: 'AmountInput',
  model: {
    prop: 'modelValue',
    event: 'update:modelValue',
  },
  props: {
    modelValue: {
      type: [String, Number],
      default: '',
    },
    numberType: {
      type: String,
      default: 'nonNegativeNumber',
    },
  },
  data() {
    return {
      value: '',
    }
  },
  watch: {
    // modelValue: {
    //   handler(val) {
    //     this.value = val
    //   },
    //   immediate: true,
    // },
  },
  computed: {},
  mounted() {},
  methods: {
    input(val) {
      if(!val) return
      if (this.numberType === 'nonNegativeNumber') {
        // 1.非负数,小数点不限制
        // 法一:
        // val = val?.replace(/[^1-9]/g, '')?.replace(/(\..*)\./g,'$1') || ''
        // 法二:
        val = val?.replace(/[^\d.]/g, '') || '' // 只保留数字和小数点
        if (val.length > 1 && val[0] === '0' && val[1] === '0') {
          // 禁止输入 00
          val = val.slice(0, -1)
        }
      } else if (this.numberType === 'positiveInteger') {
        // 2.只能输入正整数,没有小数点
        val = val.replace(/[^\d]/g, '').replace(/^0+/, '')
      }

      this.value = val
      this.$emit('input', val)
    },
    change(val) {
      this.value = val
      this.$emit('update:modelValue', val)
      this.$emit('change', val)
    },
  },
}
</script>

封装利率组件

@/components/RateInput.vue

<template>
  <div class="rate-input">
    <el-input
      v-model="value"
      @input="input"
      @change="change"
      clearable
    ></el-input>
  </div>
</template>
<script>
export default {
  name: 'RateInput',
  model: {
    prop: 'modelValue',
    event: 'update:modelValue',
  },
  props: {
    modelValue: {
      type: [String, Number],
      default: '',
    },
  },
  data() {
    return {
      value: '',
    }
  },
  watch: {
    // modelValue: {
    //   handler(val) {
    //     this.value = val
    //   },
    //   immediate: true,
    // },
  },
  computed: {},
  mounted() {},
  methods: {
    input(val) {
      // 不能输入负数:只保留数字和小数点
      val = val?.replace(/[^\d.]/g, '') || ''
      // 只能输入 0~100之间的数字,最多保留两位小数
      const pattern = /^(\d|[1-9]\d|100)(\.\d{0,2})?$/
      if (!pattern.test(val)) {
        val = val.slice(0, -1)
      }
      this.value = val
      this.$emit('input', val)
    },
    change(val) {
      // 利率必须大于0,一旦输入0就强制清空
      if (val <= 0) {
        val = ''
      }
      // this.value = val
      this.$emit('update:modelValue', val)
      this.$emit('change', val)
    },
  },
}
</script>

引入封装的金额组件与利率组件

App.vue

<template>
  <el-form
    ref="form"
    :model="formData"
    label-width="80px"
    class="demo-form-inline"
    :inline="true"
  >
    <el-form-item label="金额">
      <AmountInput v-model="formData.amout"></AmountInput>
    </el-form-item>
    <el-form-item label="利率(%)">
      <RateInput v-model="formData.rate"></RateInput>
    </el-form-item>
  </el-form>
</template>
<script>
import AmountInput from '@/components/AmountInput.vue'
import RateInput from '@/components/RateInput.vue'

export default {
  name: 'MyVue',
  components: {
    AmountInput,
    RateInput,
  },
  data() {
    return {
      formData: {
        amount: '',
        rate: '',
      },
    }
  },
  computed: {},
  mounted() {},
  methods: {},
}
</script>

image.png