需求:想要实现一个输入金额的el-input,限制只能输入数字和一个小数点。失焦数字转千分位,聚焦转为数字,超过最大值,红字提示
效果图
失焦
聚焦
报错效果
// 组件limitDialog
<template><el-dialog:visible.sync="isVisible"title="修改限额"width="420px":before-close="cancel"><el-form :model="formVal" ref="ruleForm" size="small"><el-form-itemlabel="单次交易限额"prop="single_limit":rules="[{required: true,message: '请输入单次交易限额',trigger: 'change',},{ validator: singleRule, trigger: 'change' },]"><el-inputv-model="formVal.single_limit"v-thousandmaxlength="10"type="text"@keypress.native="restrictInput('single_limit', $event)"@blur="formatOnBlur('single_limit', $event)"><template slot="suffix">{{ otherInfo.currency }}</template></el-input></el-form-item><el-form-itemlabel="每日限额"prop="daily_limit":rules="[{required: true,message: '请输入每日限额',trigger: 'change',},{ validator: dailyRule, trigger: 'change' },]"><el-inputv-model="formVal.daily_limit"maxlength="10"v-thousandtype="text"@keypress.native="restrictInput('daily_limit', $event)"@blur="formatOnBlur('daily_limit', $event)"><template slot="suffix">{{ otherInfo.currency }}</template></el-input><p class="tip" v-if="type !== 'bath'">当日已用金额 {{ otherInfo.daily_used }}{{ otherInfo.currency }}</p></el-form-item><el-form-itemlabel="每月限额"prop="monthly_limit":rules="[{required: true,message: '请输入每月限额',trigger: 'change',},{ validator: monthlyRule, trigger: 'change' },]"><el-inputv-model="formVal.monthly_limit"maxlength="10"v-thousandtype="text"@keypress.native="restrictInput('monthly_limit', $event)"@blur="formatOnBlur('monthly_limit', $event)"><template slot="suffix">{{ otherInfo.currency }}</template></el-input><p class="tip" v-if="type !== 'bath'">当月已用金额 {{ otherInfo.monthly_used }}{{ otherInfo.currency }}</p></el-form-item></el-form><div slot="footer" class="dialog-footer"><el-button @click="cancel" size="small">取 消</el-button><el-buttontype="primary"@click="handleSave"size="small":loading="isSumbitLoading">确 定</el-button></div></el-dialog>
</template><script>
import { updateCardLimitApi } from "@/services/api/cardManage.js";
import { updateObject } from "@/utils/common";
export default {data() {return {isVisible: false,isSumbitLoading: false,formVal: {single_limit: "",daily_limit: "",monthly_limit: "",id: "",},otherInfo: {currency: "USD",daily_used: "",monthly_used: "",},type: "bath",};},props: {selectedList: {type: Array,default: () => [],},},methods: {singleRule(rule, value, callback) {const numValue = Number(value);if (numValue > 10000) {callback(new Error(`输入金额不可超过单次限额(10,000.00 ${this.otherInfo.currency})`));}this.checkLimit(value, callback);},dailyRule(rule, value, callback) {const numValue = Number(value);if (numValue > 100000) {callback(new Error(`输入金额不可超过每日限额(100,000.00 ${this.otherInfo.currency})`));}this.checkLimit(value, callback);},monthlyRule(rule, value, callback) {const numValue = Number(value);if (numValue > 500000) {callback(new Error(`输入金额不可超过每月限额(500,000.00 ${this.otherInfo.currency})`));}this.checkLimit(value, callback);},checkLimit(value, callback) {const strValue = String(value || "");if (strValue === "")return callback(new Error("请输入单次交易限额"));if (strValue.endsWith("."))return callback(new Error("不能以小数点结尾"));const numValue = Number(strValue);if (isNaN(numValue)) return callback(new Error("请输入有效的数字"));if (strValue.includes(".") && strValue.split(".")[1].length > 2) {return callback(new Error("小数点后最多两位"));}callback();},restrictInput(formKey, event) {const key = event.key;const value = String(this.formVal[formKey] || "");if (event.ctrlKey || event.altKey || key.length > 1) return;// 只允许数字和小数点,限制多个小数点const isValidKey = /[0-9.]/.test(key);const hasDecimal = value.includes(".");if (!isValidKey || (key === "." && hasDecimal)) {event.preventDefault();return;}},formatOnBlur(formKey) {const strValue = String(this.formVal[formKey] || "");if (strValue && !isNaN(Number(strValue))) {this.formVal[formKey] = Number(strValue).toFixed(2);}},init(info, type) {this.isVisible = true;this.type = type;updateObject(this.formVal, info);updateObject(this.otherInfo, info);},handleSave() {this.isSubmitLoading = true;this.$refs.ruleForm.validate(async (valid) => {if (valid) {const { code } = await updateCardLimitApi({...this.formVal,id:this.type === "bath"? this.selectedList.map((item) => item.id): [this.formVal.id],});if (code == 0) {this.$message.success("修改成功");this.cancel();this.$emit("reload");}}this.isSumbitLoading = false;});},cancel() {this.isVisible = false;this.$refs.ruleForm.resetFields();updateObject(this.formVal, {single_limit: "",daily_limit: "",monthly_limit: "",id: "",});this.otherInfo.currency = "USD";},},
};
</script><style lang="scss" scoped>
.dialog-footer {text-align: right;
}
.tip {color: #999999;font-size: 12px;
}
</style>