實現效果
設置子組件
<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>