目的效果:
1、focus时是浮点数
2、blur时展示的是千分符格式
3、输入框取值时是浮点数
4、基于element-ui el-input

<template>
  <el-input
    :value="formatValue"
    v-bind="$attrs"
    v-on="inputListeners"
  />
</template>
<script>
export default {
  name: 'CurrencyInput',
  inheritAttrs: false,
  props: {
    value: {
      type: [String, Number],
      default: null,
      desc: '数值'
    }
  },
  data: () => {
    return {
      formatValue: ''
    }
  },
  computed: {
    inputListeners: function() {
      var vm = this
      // `Object.assign` 将所有的对象合并为一个新对象
      return Object.assign({},
        // 我们从父级添加所有的监听器
        this.$listeners,
        // // 然后我们添加自定义监听器,
        // // 或覆写一些监听器的行为
        {
          // 这里确保组件配合 `v-model` 的工作
          input: function(event) {
            vm.formatValue = event
            vm.$emit('input', parseFloat(vm.fmoney(event).replace(/,/g, '')))
          },
          blur: function(event) {
            vm.formatValue = vm.fmoney(vm.value)
            if (vm.$listeners.blur) {
              vm.$listeners.blur(event)
            }
          },
          focus: function(event) {
            vm.formatValue = vm.value
          }
        }
      )
    }
  },
  created() {
    this.formatValue = this.fmoney(this.value)
  },
  methods: {
    fmoney(s) {
      if (s === 0) {
        return '0.00'
      } else if (
        s === '' ||
          s == null
      ) {
        return ''
      }
      var n = 2
      var b = parseFloat(s)
      n = n > 0 && n <= 20 ? n : 2
      if (b < 0) {
        s = (-1 * parseFloat((s + '').replace(/[^\d\.-]/g, ''))).toFixed(n) + ''
      } else {
        s = parseFloat((s + '').replace(/[^\d\.-]/g, '')).toFixed(n) + ''
      }
      var l = s.split('.')[0].split('').reverse()
      var r = s.split('.')[1]
      var t = ''
      for (var i = 0; i < l.length; i++) {
        t += l[i] + ((i + 1) % 3 === 0 && (i + 1) !== l.length ? ',' : '')
      }
      if (b < 0) {
        return '-' + t.split('').reverse().join('') + '.' + r
      } else {
        return t.split('').reverse().join('') + '.' + r
      }
    }
  }
}
</script>

bug 发现:
IE浏览器下
在input的focus中

vm.formatValue = vm.fmoney(vm.value)

会导致光标移向最左边

当聚焦后主动移动光标

 focus: function(event) {
            vm.formatValue = vm.value
            if (!!window.ActiveXObject || 'ActiveXObject' in window) {
              event.target.setSelectionRange(String(vm.value).length, String(vm.value).length)
            }
          }

setSelectionRange后会阻塞,导致focus时双击事件等一些事件无效,大概会阻塞0.1s左右

参考思路:
[1]vue.js文档 自定义组件的 v-model
[2]基于vue+element的金额格式化组件


执迷不悔
21 声望0 粉丝