重构el-input-number组件实现自动千分符和默认值不为0

源码放在我的 git 仓库:完整源码

缘由

使用 el-input-number 的过程中,一直有两点困扰我:

  1. 一个就是没啥用的增减控件,这个还好,设置:controls="false"就行了,

  2. 第二个最麻烦,初始值空字符串''0 的问题。这个官方说法是设置初始值为 undefined,那么输入框内就是空的,初始值为其它假值则为 0。于是麻烦的事来了:

    • 首先,后台传回来的初始值是一般是 null,那就得自己判断并修改初始值为 undefined
    • 其次,表单校验时 0 值算非空,所以必填校验能通过,这个时候需要自己写校验器处理;
    • 最后,用户填写 0 时,又需要通过必填校验。

最尴尬的是,有业务需求需要数字在输入框中自动做千分符处理,思前想后还是重构 el-input-number 组件算了。

代码实现

查看 el-input-number 组件的源码会看到它实际上是基于 el-input 组件开发的,其遵循的大体逻辑如下:

  1. 监听组件 props 中的 value 值,将其赋给组件内部的 currentValue
  2. 监听 el-input 组件的 input 事件,将输入值赋值给 userInput
  3. 监听 el-input 组件的 blurchange 事件,令 userInput = null
  4. 根据 currentValueuserInput 计算 el-inputvalue 属性值 displayValue

不难想到,只要在计算 displayValue 值时增加处理逻辑即可。核心代码如下

export default {
    
    
  computed: {
    
    
    //...
    displayValue() {
    
    
      // 用户持续输入时,不计算页面展示值,直接返回
      if (this.userInput !== null) {
    
    
        return this.userInput
      }

      return this.formatValue(this.currentValue, this.precision)
    }
  }

  methods: {
    
    
    formatValue(value, precision) {
    
    
      let reg = /(\d)(?=(?:\d{3})+$)/g
      if (typeof value === 'number' && precision !== undefined) {
    
    
        let val = value.toFixed(precision)
        return val.split('.').length > 1
          ? val.split('.')[0].replace(reg, '$1,') + '.' + val.split('.')[1]
          : val.split('.')[0].replace(reg, '$1,')
      } else if (typeof value === 'string' && precision !== undefined) {
    
    
        let val = value.replace(/,/g, '')
        val = this.toPrecision(val, precision)
        return val.split('.').length > 1
          ? val.split('.')[0].replace(reg, '$1,') + '.' + val.split('.')[1]
          : val.split('.')[0].replace(reg, '$1,')
      }
    },
    //...
  }
};

效果如下

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/sinat_36521655/article/details/107486516