实现效果
设置子组件
<template><el-inputref="money"v-model.trim="money":placeholder="placeholder"v-bind="$attrs"v-on="$listeners"@input="formatNumber(money,'money')"@keyup.enter.native="moneyChange()"@blur="moneyChange()"><template slot="append">人</template></el-input>
</template><script>
export default {name: 'MoneyInput',props: {value: {type: null,required: true},placeholder: {type: String,default: '请输入金额'},enterFuc: {type: Function,default: () => {}},data: {type: null,default: null},template: { //是否展示单位type: String,default: ''}},data() {return {money: this.value,}},watch: {value(newValue, oldValue) {this.money = newValuethis.formatNumber(this.money, 'money')}},mounted() {this.formatNumber(this.money, 'money')},methods: {fmresource(s) {if (s === '' || s === null || s === '.00' || s === undefined) {return ''}if (s === '-') {return '-'}var lose = ''// 负号if (s < 0) { // 判断是否是负数s = (s + '').substring(1)// 截取-号lose = '-'}s = s + ''// n = n > 0 && n <= 20 ? n : 2;.toFixed(n)// s = parseFloat((s + "").replace(/^[^\d.-]/g, "")) + "";var l = s.split('.')[0].split('').reverse(); var r = ''; var t = ''if (s.indexOf('.') > -1) {if (s.split('.')[1] !== null && s.split('.')[1] !== undefined) {if (s.split('.')[1].length > 2) {s = Number(s).toFixed(2)}r = ('.' + s.split('.')[1])} else {r = ''}}for (let i = 0; i < l.length; i++) {t += l[i] + ((i + 1) % 3 === 0 && (i + 1) !== l.length ? ',' : '')}return lose + '' + t.split('').reverse().join('') + r// 拼接},formatNumber(value, name) {this.$emit('update:data', value)value = value + ''// 获取input的dom对象,这里因为用的是element ui的input,所以需要这样拿到const input = this.$refs[name].$el.getElementsByTagName('input')[0]// 获取当前光标的位置const cursorIndex = input.selectionStart// 字符串中光标之前-的个数const lineNumOfCursorLeft = (value.slice(0, cursorIndex).match(/,/g) || []).length// 去掉所有,的字符串const noLine = value.replace(/,/g, '')// 重新格式化const newvalue = this.fmresource(noLine.replace(/[^\d\.-]/g, ''))// .replace(/(\d{4})/g, '$1 ').replace(/ $/, '')// 改后字符串中原光标之前,的个数const newLineNumOfCursorLeft = (newvalue.slice(0, cursorIndex).match(/,/g) || []).length// 光标在改后字符串中应在的位置const newCursorIndex = cursorIndex + newLineNumOfCursorLeft - lineNumOfCursorLeft// 赋新值,nextTick保证-不能手动输入或删除,只能按照规则自动填入this.$nextTick(() => {this.money = newvalue// 修正光标位置,nextTick保证在渲染新值后定位光标this.$nextTick(() => {// selectionStart、selectionEnd分别代表选择一段文本时的开头和结尾位置input.selectionStart = newCursorIndexinput.selectionEnd = newCursorIndex})})},moneyChange() {const v = this.money ? (this.money + '').replace(/,/g, '').replace(new RegExp(/(\d+)(\.)(\d*)(\2*)(\d*)/g), '$1$2$3$5') : 0const money = Object.is(Number(v), NaN) ? 0 : Number(v)this.$emit('input', money)this.enterFuc()}}
}
</script>
在父组件引入
引入组件
import MoneyInput from “./compontents/index”
components: {MoneyInput},
使用
<Money-input v-model.trim="project.hospitalnumber" template="append" style="width: 100%"></Money-input>