只能输入 数字/小数点的数字和金额校验

本文详细介绍了金额组件的设计与实现过程,包括金额的输入验证、千分位转换、大写金额转换等功能,以及如何在Vue中使用Vuex进行状态管理。

废话不多说-直接上代码

<!--
  @description: 金额组件
  @Modifier: 肖文龙
  @routerPath:
  @date: 2020/1/16-10:15
-->

<template>
  <section class="totalMoney">
    <el-input
      v-if="inputType"
      v-model="moneyText"
      :size="size"
      :disabled="disabled"
      :style="{'width':width}"
      v-on="$listeners"
      @focus="onFocus"
    />
    <!-- 输入框 -->
    <el-input
      v-else-if="!inputType"
      v-model="moneyValue[name]"
      :size="size"
      :disabled="disabled"
      :style="{'width':width}"
      v-on="$listeners"
      @blur="onBlur"
      @input="inputChanged"
    />
    <!-- 元 -->
    <span v-if="unitStust" style="margin-left: 10px;">{{ language.yuan }}</span>
    <!-- 大写 -->
    <p v-if="great" class="amount_words">
      ( <!-- {{ language.Capitalization }} -->大写:<span>{{ numberChinese(moneyValue[name]) }} </span>)
    </p>
  </section>
</template>

<script>
import { moneyFormat, numberChinese } from '@assets/js/utils'
import { mapGetters } from 'vuex'
// 常用方法
export default {
  name: 'Money',
  props: {
    // json对象
    moneyValue: {
      type: Object,
      default: function() {
        return {}
      }
    },
    // 金额输入/变更的字段
    name: {
      type: String,
      default: ''
    },
    // 是否可以输入负数  布尔值
    negative: {
      type: Boolean,
      default: false
    },
    // inpit框尺寸大小
    size: {
      type: String,
      default: 'small'
    },
    // 是否使用千分位 布尔值
    thousands: {
      type: Boolean,
      default: false
    },
    // 是否展示大写汉字金额
    great: {
      type: Boolean,
      default: false
    },
    // 是否展示单位
    unitStust: {
      type: Boolean,
      default: false
    },
    // 是否可编辑
    disabled: {
      type: Boolean,
      default: false
    },
    // 保留几位小数,默认为两位小数
    unitFixed: {
      type: Number,
      default: 2
    },
    // input框宽度,默认为200px
    width: {
      type: String,
      default: '200px'
    }
  },
  data() {
    return {
      maxNum: '99999999999999', // 最大限制金额
      inputType: true, // 是否展示千分位转换后的input框
      money: '', // 千分位转换前的参数
      moneyText: '', // 千分位转换后的参数
      numberChinese: numberChinese // 金额转大写
    }
  },
  computed: {
    /* langcommon 国际化 info 用户信息 isCollapse菜单栏状态*/
    ...mapGetters(['language'])
  },
  watch: {
    'moneyValue': {
      handler(newVal, oldVal) {
        this.thousandsLoad()// 千分位转换
      },
      deep: true
    }
  },
  created() {
    this.thousandsLoad()// 千分位转换
  },
  methods: {
    // 金额输入校验-规则
    onlyNumber(type) {
      if (this.moneyValue[this.name]) {
      // 根据网上-修改的- Start

        // 是否可以为负数
        if (this.negative === true) {
        // 先把非数字的都替换掉,除了数字和".","-"
          this.moneyValue[this.name] = this.moneyValue[this.name].replace(/[^\d\.-]/g, '')
        } else {
          // 先把非数字的都替换掉,除了数字和.
          this.moneyValue[this.name] = this.moneyValue[this.name].replace(/[^\d\.]/g, '')
        }
        // 前两位不能是0加数字
        this.moneyValue[this.name] = this.moneyValue[this.name].replace(/^(0)*(\d[0-9]*)/g, '$2')
        // 必须保证第一个为数字和"-",而不是.
        this.moneyValue[this.name] = this.moneyValue[this.name].replace(/^\./g, '')
        // 保证只有出现一个.而没有多个.
        this.moneyValue[this.name] = this.moneyValue[this.name].replace(/\.{2,}/g, '.')
        // 保证.只出现一次,而不能出现两次以上
        this.moneyValue[this.name] = this.moneyValue[this.name].replace('.', '$#$').replace(/\./g, '').replace('$#$', '.')

        // 是否可以为负数
        if (this.negative === true) {
        // 保证只有出现一个-而没有多个-
          this.moneyValue[this.name] = this.moneyValue[this.name].replace(/\-{2,}/g, '-')
          // 保证-只出现一次,而不能出现两次以上
          this.moneyValue[this.name] = this.moneyValue[this.name].replace('-', '$#$').replace(/\-/g, '').replace('$#$', '-')
        }
        // 限制最大金额
        if (Number(this.moneyValue[this.name]) >= Number(this.maxNum)) this.moneyValue[this.name] = this.maxNum
        // 失去焦点时
        if (type === 'blur') {
        // 保留几位小数
          const num = 0// 初始值
          const str = String(this.moneyValue[this.name]).includes('.') ? String(this.moneyValue[this.name]).split('.')[1] : ''
          if (str.length > this.unitFixed) {
            this.moneyValue[this.name] = this.moneyValue[this.name] ? Number(this.moneyValue[this.name]).toFixed(this.unitFixed) : num.toFixed(this.unitFixed)
          }
        }
      // 根据网上-修改的- End
      }
    },
    // 千分位转换
    thousandsLoad() {
      // 判断是否使用千分位
      if (this.thousands) {
        this.moneyText = moneyFormat(this.moneyValue[this.name])// 千分位转换
      } else {
        this.moneyText = this.moneyValue[this.name]
      }
    },
    // 监听输入框事件
    inputChanged($event) {
      this.onlyNumber()// 金额输入校验
      this.$emit('input')
    },
    // 千分位转换后的input框-获取焦点时
    onFocus() {
      this.inputType = false
    },
    //  千分位转换之前的input框-失去焦点时
    onBlur($event) {
      this.onlyNumber('blur')// 金额输入校验-规则
      this.$emit('input')
      this.inputType = true
    }
  }
}
</script>

<style scoped lang="less">
  /deep/.amount_words {
    display: inline-block;
    font-weight: bold;
    font-size: 14px;

    span {
      color: red;
    }
  }

/*input 金额右对齐*/
  /deep/.el-input__inner {
    text-align: right;
  }
</style>

 

 

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值