Vue实现金钱输入框组件自动带千位逗号

新建PriceInput.vue

<template>
  <div id="bord">
    <el-input
    v-model="inputValue"
    v-bind="$attrs"
    :maxlength="maxlength"
    @input="handleInput"
    @focus="handleFocus"
    @blur="handleBlur"
    @change="handleChange"
  >
    <template slot="append">
      <slot name="append"></slot>
    </template>
  </el-input>

  </div>

</template>

<script>
import { inputNumber } from '@/utils/inputNumber'
import { formatMoney } from '@/utils/formatMoney'
export default {
  // name:'priceInput',
  props: {
    value: {
      type: [String, Number],
      default: ''
    },
    // 金额位数格式(a-b);a:整数位数;b:小数位数
    format: {
      type: String,
      default: '9-2'
    }
  },
  data () {
    return {
      inputValue: '',
      inputing: false
    }
  },
  computed: {
    integerNum () {
      return Number(this.format.split('-')[0])
    },
    decimalNum () {
      return Number(this.format.split('-')[1])
    },
    maxlength () {
      return this.integerNum + (this.decimalNum > 0 ? this.decimalNum + 1 : this.decimalNum)
    }
  },
  watch: {
    value: {
      immediate: true,
      handler (n) {
        if (!n) {
          this.inputValue = n
          return
        }
        if (this.inputing) {
          this.inputValue = n
        } else {
          this.inputValue = formatMoney(inputNumber(n.toString()), this.format)
        }
      }
    }
  },
  methods: {
    handleInput (val) {
      this.inputing = true
      let money = inputNumber(val)
      const format = this.format
      const intNum = Number(format.split('-')[0])
      const decimalNum = Number(format.split('-')[1])
      const moneyArr = money.split('.')
      moneyArr[0] = moneyArr[0].length > intNum ? moneyArr[0].substr(0, intNum) : moneyArr[0]
      if (moneyArr[1]) {
        moneyArr[1] = moneyArr[1].length > decimalNum ? moneyArr[1].substr(0, decimalNum) : moneyArr[1]
      }
      money = moneyArr.join('.')
      this.inputValue = money
      let value = ''
      if (money === '-' || money === '.') {
        value = ''
      } else if (money !== '') {
        value = Number(inputNumber(money))
      }
      this.$emit('input', value)
    },
    handleChange (val) {
      this.inputing = true
      this.$emit('change', Number(val.replaceAll(',', '')))
    },
    handleBlur (e) {
      this.inputing = false
      this.inputValue = formatMoney(inputNumber(e.target.value), this.format)
      this.$emit('blur', e)
    },
    handleFocus (e) {
      this.inputing = true
      this.inputValue = inputNumber(this.inputValue)
      this.$emit('focus', e)
    }
  }
}
</script>
<style>
#bord>.el-input>input{
  border: 0;
  outline: none;/* 清除边框 */
  text-align: right;
  font-size: 18px;
  background-color:transparent;/* 输入透明背景 */
}
</style>

formatMoney.js格式化金额

/**
 * 格式化金额
 * @param money { String / Number } 金额
 * @param format { String } a-b:限制输入的字符长度,a:整数长度,b:小数长度
 * @returns {string|null}
 */
export const formatMoney = (money, format) => {
  if (typeof money === 'number') {
    money = money.toString()
  }
  if (money === '-' || !money) return money
  if (!format) format = '11-2'
  const intNum = Number(format.split('-')[0])
  const decimalNum = Number(format.split('-')[1])
  const moneyArr = money.split('.')
  moneyArr[0] = moneyArr[0].length > intNum ? moneyArr[0].substr(0, intNum) : moneyArr[0]
  if (moneyArr[1]) {
    moneyArr[1] = moneyArr[1].length > decimalNum ? moneyArr[1].substr(0, decimalNum) : moneyArr[1]
  }
  money = moneyArr.join('.')
  const isNegativeNum = money.startsWith('-')
  const pointPosition = money.indexOf('.')
  const decimal = pointPosition !== -1 ? money.substr(pointPosition) : ''
  const integer = Math.abs(parseInt(money).toString()).toString()
  const integerArrReverse = integer.split('').reverse().join('')
  const moneyStringify = `${isNegativeNum ? '-' : ''}${integerArrReverse.replace(/(\d{3})(?=\d)/g, '$1,').split('').reverse().join('')}${decimal}`
  return moneyStringify
}

inputNumber.js格式化为普通数字格式

// 此方法用来实现将一个字符串通过replace方法,格式化为普通数字格式(包括正负整数、正负浮点数都支持)
export const inputNumber = val => {
  if (val === '-' || !val) return val
  if (val === '.') return ''
  // 下列代码中正则表达式的非捕获组(?<=)在IE浏览器中不支持,所以弃用
  // const reg1 = /[^\d|^\-|\^.]/g // 匹配所有非数字,非-,非.的字符
  // const reg2 = /(?<=[\.|\-])[^\d]/g // 匹配所有.和-字符后的非数字字符
  // const reg3 = /(?<=\.\d*)\./g // 匹配小数后的.
  // const reg4 = /(?<=\d)\-/g // 匹配-后面的非数字
  // return val.replace(reg1, '').replace(reg2, '').replace(reg3, '').replace(reg4, '')

  const reg1 = /[^\d|\-|\.]/g
  const reg2 = /(\d|\.)\-+/g
  const str = val.replace(reg1, '').replace(reg2, '$1')
  const pointArr = str.split('.')
  let value = ''
  if (pointArr.length > 1) {
    pointArr.forEach((item, index) => {
      value = value + item
      if (!index) {
        value = value + '.'
      }
    })
  } else {
    value = str
  }
  return value
}

使用案例

  <PriceInput
         v-model="yourModel"
         :format="yourFormat"
         @input="yourInputHandler"
         @change="yourChangeHandler"
         @blur="yourBlurHandler"
         @focus="yourFocusHandler"
       />
 export default {
     data() {
       return {
         yourModel: '', // 初始化你的模型值
         yourFormat: '11-2' // 初始化你的格式
       };
     },
     methods: {
       yourInputHandler(value) {
         console.log('Input:', value);
       },
       yourChangeHandler(newValue) {
         console.log('Changed:', newValue);
       },
       yourBlurHandler(event) {
         console.log('Blurred:', event);
       },
       yourFocusHandler(event) {
         console.log('Focused:', event);
       }
     }
   }

在这里插入图片描述
在这里插入图片描述

  • 11
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值