废话不多说-直接上代码
<!--
@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>