vant金额输入框
1.在components中新建文件夹currency,新建index.js
import Currency from './src/currency.vue'Currency.install = function (Vue) {Vue.component(Currency.name, Currency)
}export default Currency
2.在currency中新建文件夹src,在src中间currency.vue。写入核心代码
<template><van-field v-model="liveValue" :name="name" :placeholder="placeholder" :disabled="disabled" :readonly="readonly" @focus="handleFocus" @blur="handleBlur" @change.native="handleChange" v-bind="$attrs" @keydown.native="handleKeydown"></van-field>
</template><script>
import { formatter, unFormatter, numberKeyCodes, decimalKeyCodes, plusKeyCodes, minusKeyCodes, operKeyCodes } from '../../currentcy.js'
export default {name: 'Sjjcurrency',props: {name: 'String',value: {type: [String, Number],default: ''},format: {type: String,default: '16|2'},placeholder: String,separator: {type: String,default: ','},decimalSymbol: {type: String,default: '.'},disabled: {type: Boolean,default: false},readonly: {type: Boolean,default: false},rounding: {type: Boolean,default: false},appendKeyCodes: Array,preFormatter: Function},components: {UnInput},data () {return {hiddenValue: '', // 合法金额值liveValue: '' // 展示值}},created () {let userFormatVal = this.value + ''if (this.preFormatter) {userFormatVal = this.preFormatter(userFormatVal)}this.liveValue = formatter(userFormatVal + '', this.separator, this.decimalSymbol, this.format, this.integerFormat, this.rounding)this.hiddenValue = unFormatter(this.liveValue, this.separator)},watch: {value (val, oldVal) {let userFormatVal = this.value + ''if (this.preFormatter) {userFormatVal = this.preFormatter(userFormatVal)}this.liveValue = formatter(userFormatVal + '', this.separator, this.decimalSymbol, this.format, this.integerFormat)this.hiddenValue = unFormatter(this.liveValue, this.separator)}},methods: {focus () {let inputInner = this.$el.querySelector('.van-field_control')inputInner.focus()},blur () {let inputInner = this.$el.querySelector('.van-field_control')inputInner.blur()},select () {let inputInner = this.$el.querySelector('.van-field_control')inputInner.select()},handleFocus (event) {this.liveValue = this.hiddenValuethis.$emit('focus', event)},handleBlur (event) {let userFormatVal = this.liveValueif (this.preFormatter) {userFormatVal = this.preFormatter(userFormatVal)}this.liveValue = formatter(userFormatVal + '', this.separator, this.decimalSymbol, this.format, this.integerFormat, this.rounding)this.hiddenValue = unFormatter(this.liveValue, this.separator)this.$emit('input', this.hiddenValue)this.$nextTick(() => {this.$emit('blur', event)})},handleChange (val) {if (/[\u4e00-\u9fa5]/g.test(val)) { // 非IE,忽略可输入的中文val = this.hiddenValue}let userFormatVal = valif (this.preFormatter) {userFormatVal = this.preFormatter(val)}this.liveValue = formatter(userFormatVal + '', this.separator, this.decimalSymbol, this.format, this.integerFormat, this.rounding)this.hiddenValue = unFormatter(this.liveValue, this.separator)this.$emit('input', this.hiddenValue)this.$nextTick(() => {this.$emit('change', this.hiddenValue)})},handleKeydown (event) {if (this.readonly || this.disabled) {return}let keyCode = event.keyCodeif (event.shiftKey) {keyCode = -9 + '' + keyCode}if (event.ctrlKey) {keyCode = -7 + '' + keyCode}// 获取光标位置let cursurPosition = 0let inputInner = this.$el.querySelector('.van-field_control')if (inputInner) {if (inputInner.selectionStart !== null && inputInner.selectionStart !== undefined) {// 非IE、IE11cursurPosition = inputInner.selectionStart} else {// IE10-let range = document.selection.createRange()range.moveStart('character', -inputInner.val().length)cursurPosition = range.text.length}} else {cursurPosition = -1}keyCode = parseInt(keyCode)let allowKeyCodes = [...numberKeyCodes,...decimalKeyCodes,...operKeyCodes,...plusKeyCodes,...minusKeyCodes]if (this.appendKeyCodes && this.appendKeyCodes.length) {allowKeyCodes = allowKeyCodes.concat(this.appendKeyCodes)}// let signalKeyCodes = plusKeyCodes.concat(minusKeyCodes)if (allowKeyCodes.indexOf(keyCode) < 0 || (this.liveValue.indexOf('.') >= 0 && decimalKeyCodes.indexOf(keyCode) >= 0) || ((this.liveValue.indexOf('+') >= 0 || this.liveValue.indexOf('-') >= 0) && minusKeyCodes.indexOf(keyCode) >= 0) || ((this.liveValue.indexOf('+') >= 0 || this.liveValue.indexOf('-') >= 0) && plusKeyCodes.indexOf(keyCode) >= 0) || (cursurPosition > 0 && plusKeyCodes.concat(minusKeyCodes).indexOf(keyCode) >= 0)) {event.preventDefault()} else {if (cursurPosition === 0 && (plusKeyCodes.indexOf(keyCode) >= 0 || minusKeyCodes.indexOf(keyCode) >= 0)) {// if ((this.liveValue.indexOf('-') < 0 && minusKeyCodes.indexOf(keyCode) >= 0) || (this.liveValue.indexOf('+') < 0 && plusKeyCodes.indexOf(keyCode) >= 0)) { // 可输入+if ((this.liveValue.indexOf('-') < 0 && minusKeyCodes.indexOf(keyCode) >= 0)) {// 不可输入+} else {event.preventDefault()}}}}}
}
</script>
3.currentcy.js
import { BigDecimal, RoundingMode } from 'bigdecimal'
export const numberKeyCodes = [44, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105] // 允许的数字键的keyCode
export const decimalKeyCodes = [190, 110] // 小数键的keyCode
export const plusKeyCodes = [107, -9187] // 正号的keyCode 【小键盘+, 187=(配合shift使用)】
export const minusKeyCodes = [109, 189] // 负号的keyCode
export const operKeyCodes = [9, 46, 8, 37, 39, 35, 36, -767, -786] // 操作特殊字符的KeyCodefunction __getIntDigitLength__ (intDigitStr) {let len = {}let intLength = ''let decimalLength = ''intDigitStr = intDigitStr.trim()if (intDigitStr && intDigitStr !== '|' && /^(\d*)\|(\d*)$/g.test(intDigitStr)) {intLength = RegExp.$1decimalLength = RegExp.$2len.intLength = intLengthlen.decimalLength = decimalLengthreturn len} else {return false}
}function __getStringRegExp__ (str) {try {if (str && /[\][{}()*+?.\\^$|]/g.test(str)) {if (str !== '\\') return '\\' + strelse return '\\'} else return str || ''} catch (e) {throw new Error('__getStringRegExp__:' + e.message)}
}function __removeSeparator__ (value, separator) {try {// var _me = thisvar separatorRegExp = __getStringRegExp__(separator) || ''if (separatorRegExp) {var dh = new RegExp(separatorRegExp, 'img')if (value && dh.test(value)) {return value.replace(dh, '')}}return value || ''} catch (e) {throw new Error('__removeSeparator__:' + e.message)}
}export function formatter (value, separator, decimalSymbol, intDigitStr, isIntegerOnly, rounding) {try {// let valueValid = falsevar _currencyValue = {intLength: '16',decimalLength: '2',NegativeValue: '',intValue: '',decimalValue: '',formatValue: ''}value = value + ''if (!value || value === '-' || value === '+') {return ''}// var _me = this,var separatorRegExp, _value, __decimalLen, __intLen // 整数部分var lenObj = __getIntDigitLength__(intDigitStr)if (lenObj) {_currencyValue.intLength = lenObj.intLength_currencyValue.decimalLength = lenObj.decimalLength}__intLen = parseInt(_currencyValue.intLength, 10)__decimalLen = rounding ? parseInt(_currencyValue.decimalLength, 10) + 1 : parseInt(_currencyValue.decimalLength, 10)// var isNegative = false // 是否负数var valArr = /^-([^-]+)$/.exec(value)if (valArr) {// isNegative = true // 表示是负数_currencyValue.NegativeValue = '-'value = valArr[1]}if (separator === '') {return ''}_value = value // 整数部分_currencyValue.decimalValue = '' // 小数部分if (value.indexOf('.') > -1) { // 若含有小数点,则处理得到整数部分和小数部分_currencyValue.decimalValue = value.substring(value.indexOf('.') + 1)_value = value.substring(0, value.indexOf('.'))}// 若未输入整数部分,则自动取成0----------------------------------------------------_value = _value === '' ? '0' : _value// _value === '' ? _value = '0' : _value = _valueif (separator !== '') {separatorRegExp = __getStringRegExp__(separator)_value = __removeSeparator__(_value, separator) // 去分隔符}if (isNaN(_value) || isNaN(_currencyValue.decimalValue) || isNaN(value)) { // 若不是数字则报错,isNaN('')=falsereturn ''}// modify beginif (isIntegerOnly && value.indexOf('.') < 0) { // 纯整数格式化且不含.时,对纯整数进行格式化if (_currencyValue.decimalLength !== '') {if (_value.length > __decimalLen) {_currencyValue.decimalValue = _value.substring(_value.length - __decimalLen)_value = _value.substring(0, _value.length - __decimalLen)} else {var _s = _valuefor (var i = 0; i < (__decimalLen - _value.length); i++) {_s = '0' + _s}_currencyValue.decimalValue = _s_value = '0'}} else {_currencyValue.decimalValue = ''}} else {if (_currencyValue.decimalLength !== '') {if (_currencyValue.decimalValue.length < __decimalLen) {var _d = _currencyValue.decimalValuefor (var j = 0; j < (__decimalLen - _currencyValue.decimalValue.length); j++) {_d += '0'}_currencyValue.decimalValue = _d} else {if (_currencyValue.decimalValue.length > __decimalLen) {// valueValid = false}_currencyValue.decimalValue = _currencyValue.decimalValue.substring(0, __decimalLen)}}}// modify endvar _intVal = _valueif (_currencyValue.intLength !== '') { // 若存在整数位的限制if (_currencyValue.intLength < _intVal.length) {// valueValid = false}_intVal = _intVal.substring(0, __intLen)}_currencyValue.intValue = _value = _intVal// 整数处理完毕 endvar _digitpoint = (_currencyValue.decimalValue ? decimalSymbol : '')let zeroFilter = (_currencyValue.intValue + '').split('').filter(x => {return x !== '0'})if (zeroFilter.length === 0) { // 输入所有位数都是0的情况,设置后直接返回_currencyValue.intValue = '0'let zeroFilterDec = (_currencyValue.decimalValue + '').split('').filter(x => {return x !== '0'})// 去掉输入全部为0时的负号if (zeroFilterDec.length === 0) {_currencyValue.NegativeValue = ''}_currencyValue.formatValue = _currencyValue.NegativeValue + '0' + (_currencyValue.decimalValue !== '' ? (_digitpoint + _currencyValue.decimalValue) : '')if (rounding) {_currencyValue.formatValue = new BigDecimal(_currencyValue.formatValue).setScale(__decimalLen - 1, RoundingMode.HALF_UP()).toString()}return _currencyValue.formatValue}// 处理整数的前缀0if (/^0+/g.test(_currencyValue.intValue) && !(/^(0+)$/g.test(_currencyValue.intValue)) && !(/^0$/g.test(_currencyValue.intValue))) {_currencyValue.intValue = _currencyValue.intValue.replace(/^0+/, '')_value = _intVal = _currencyValue.intValue}if (rounding) {let rVal = _value + _digitpoint + _currencyValue.decimalValuelet roundingVal = new BigDecimal(rVal).setScale(__decimalLen - 1, RoundingMode.HALF_UP()).toString()_value = roundingVal.substring(0, roundingVal.indexOf(_digitpoint))_currencyValue.decimalValue = roundingVal.substring(roundingVal.indexOf(_digitpoint) + 1)}// 整数部分的分隔符处理开始if (separator !== '') {_value = _value + separatorvar re = new RegExp('(\\d)(\\d{3}' + separatorRegExp + ')') // 以3个字符串为一组while (re.test(_value)) {_value = _value.replace(re, '$1' + separator + '$2')}_value = _value.replace(new RegExp(separatorRegExp + '$'), '') // 去掉末尾的分隔符}_currencyValue.formatValue = _currencyValue.NegativeValue + _value + (_currencyValue.decimalValue !== '' ? (_digitpoint + _currencyValue.decimalValue) : '')if (+_currencyValue.formatValue < 0) {// 去除-号return _currencyValue.formatValue.substr(1)} else {return _currencyValue.formatValue}// return _currencyValue.formatValue} catch (e) {throw new Error('formatter', e.message)}
}
export function unFormatter (value, separator) {return (value + '').replace(new RegExp(separator, 'ig'), '')
}
4.然后就是最愉快的代码引入了(代表10位整数6位小数)
<currency v-model="money" :format="10|6" placeholder="请输入内容" />