el-input实现金额输入

news2025/3/5 0:16:06

需求:想要实现一个输入金额的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-item
                label="单次交易限额"
                prop="single_limit"
                :rules="[
                    {
                        required: true,
                        message: '请输入单次交易限额',
                        trigger: 'change',
                    },
                    { validator: singleRule, trigger: 'change' },
                ]"
            >
                <el-input
                    v-model="formVal.single_limit"
                    v-thousand
                    maxlength="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-item
                label="每日限额"
                prop="daily_limit"
                :rules="[
                    {
                        required: true,
                        message: '请输入每日限额',
                        trigger: 'change',
                    },
                    { validator: dailyRule, trigger: 'change' },
                ]"
            >
                <el-input
                    v-model="formVal.daily_limit"
                    maxlength="10"
                    v-thousand
                    type="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-item
                label="每月限额"
                prop="monthly_limit"
                :rules="[
                    {
                        required: true,
                        message: '请输入每月限额',
                        trigger: 'change',
                    },
                    { validator: monthlyRule, trigger: 'change' },
                ]"
            >
                <el-input
                    v-model="formVal.monthly_limit"
                    maxlength="10"
                    v-thousand
                    type="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-button
                type="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>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2309727.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

双碳战略下的智慧能源实践:安科瑞储能管理系统助力企业绿色转型

在全球碳中和目标加速推进的背景下&#xff0c;中国“十四五”规划明确提出构建以新能源为主体的新型电力系统&#xff0c;储能技术成为支撑能源结构转型的核心要素。安科瑞储能能量管理系统作为企业级智慧能源解决方案的核心载体&#xff0c;凭借其技术创新与场景适配能力&…

《鸢尾花数学大系:从加减乘除到机器学习》开源资源

《鸢尾花数学大系&#xff1a;从加减乘除到机器学习》开源资源 Gitee&#xff1a;https://gitee.com/higkoo/ bilibili&#xff1a;https://space.bilibili.com/513194466 GitHub&#xff1a;https://github.com/Visualize-ML

本地部署HDFS集群

首先完成本地部署大数据集群前置准备&#xff0c;可参考&#xff1a; 本地部署大数据集群前置准备https://blog.csdn.net/m0_73641796/article/details/145994787?spm1001.2014.3001.5501 1.下载hadoop 下载Hadoop安装包&#xff0c;本文用的是hadoop-3.3.4.tar.gz 2. 集群…

10.【线性代数】—— 四个基本子空间

十、 四个基本子空间 1. 列空间 C ( A ) C(A) C(A) in R m R^m Rm2. 零空间 N ( A ) N(A) N(A) in R n R^n Rn3. 行空间 C ( A T ) C(A^T) C(AT) in R n R^n Rn4. 左零空间 N ( A T ) N(A^T) N(AT) in R m R^m Rm综述5. 新的向量空间 讨论矩阵 A m ∗ n A_{m*n} Am∗n​…

基于vue框架的游戏商城系统cq070(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。

系统程序文件列表 项目功能&#xff1a;用户,分类,商品信息,游戏高手,游戏代练 开题报告内容 基于Vue框架的游戏商城系统开题报告 一、研究背景与意义 随着互联网技术的飞速发展和游戏产业的蓬勃兴起&#xff0c;游戏商城作为游戏产业链中的重要一环&#xff0c;迎来了前所…

我代表中国受邀在亚马逊云科技全球云计算大会re:Invent中技术演讲

大家好我是小李哥&#xff0c;本名叫李少奕&#xff0c;目前在一家金融行业公司担任首席云计算工程师。去年5月很荣幸在全球千万名开发者中被选为了全球亚马逊云科技认证技术专家&#xff08;AWS Hero&#xff09;&#xff0c;是近10年来大陆地区仅有的第9名大陆专家。同时作为…

css3d放置的面板方向不对问题排查

以往在threejs左手坐标系下&#xff0c;cameranew THREE.Vector3(0, 0, 1)&#xff0c;好像在贴css3d的时候从来不会出问题。而这次接到一个朋友是用右手坐标系的&#xff0c;camera默认不设置方向&#xff0c;则应该是&#xff08;0&#xff0c;1&#xff0c;0&#xff09; c…

网络安全法与等级保护 PPT 精华汇总

资源描述 本资源文件为《网络安全法与等级保护》的PPT精华汇总&#xff0c;内容涵盖了网络安全法与等级保护的总体框架及相关标准规范。该PPT详细介绍了网络安全法与等级保护的各个章节和条款&#xff0c;并提供了基础类和应用类的相关标准文件&#xff0c;帮助读者全面了解和…

探秘基带算法:从原理到5G时代的通信变革【十】基带算法应用与对比

文章目录 三、算法在现代通信系统中的应用3.1 5G 通信中的应用3.1.1 信道编码与调制解调3.1.2 大规模 MIMO 技术3.1.3 案例分析&#xff1a;5G 基站与终端实现 3.2 卫星通信中的应用3.2.1 抗干扰与纠错编码3.2.2 信号处理与调制解调3.2.3 案例分析&#xff1a;卫星通信系统实例…

io学习----->标准io

思维导图&#xff1a; 一.io的作用 io是实现对文件的操作&#xff0c;把运行结果存到文件中&#xff0c;读取文件的数据&#xff0c;方便后期查询。 二.io的概念 io是指系统 和外部设备或用户之间的数据交互 I:input 表示数据从外部设备输入到内存中&#xff1b; O:output…

LeetCode 面试题 17.19. 消失的两个数字

LeetCode 面试题 17.19. 消失的两个数字 思路&#x1f9d0;&#xff1a; 运用位运算&#xff0c;我们先创建一个变量tmp&#xff0c;依次异或nums和1~N所有整数&#xff0c;此时就可以得到两个数的异或值。 然后通过右移操作&#xff0c;逐位检查tmp中的每一位&#xff0c;找到…

KaiwuDB| Google Spanner 经典架构回顾

前言 大数据时代 &#xff0c;随着移动互联网和物联网技术的发展 &#xff0c; 全球数据量呈现爆发式增长&#xff0c;已经远远超出集中式单机数据库的处理能力。CCF 数据库专委 2021 年发布的《“十四五”数据库发展趋势与挑战》显示&#xff0c; 各行各业海量数据的管理需求…

拼电商客户管理系统

内容来自&#xff1a;尚硅谷 难度&#xff1a;easy 目 标 l 模拟实现一个基于文本界面的 《 拼电商客户管理系统 》 l 进一步掌握编程技巧和调试技巧&#xff0c;熟悉面向对象编程 l 主要涉及以下知识点&#xff1a; 类结构的使用&#xff1a;属性、方法及构造器 对象的创建与…

项目准备(flask+pyhon+MachineLearning)- 1

目录 这是一篇学习笔记 1. 搭建项目 2.前期准备工作 3.创建用户(user)模板 这是一篇学习笔记 目的&#xff1a;用flask快速实现发布有关机器学习的项目&#xff0c;掌握flask框架&#xff0c;机器学习模型的存储和调用。 1. 搭建项目 使用pycharm创建项目&#xff0c;fl…

1.2.2 使用Maven方式构建Spring Boot项目

本次实战通过Maven方式构建了一个Spring Boot项目&#xff0c;实现了简单的Web应用。首先&#xff0c;创建了Maven项目并设置好项目名称、位置、构建系统和JDK等。接着&#xff0c;添加了Spring Boot的父项目依赖和web、thymeleaf起步依赖。然后&#xff0c;创建了项目启动类He…

C++中函数的调用

************* C topic&#xff1a;call functions ************* 1、为什么要用函数 In every codes, functions are the crucial parts. There are many advantages of the functions. But I introduce two of them. The first usage of the functions is reuse. And th…

【Linux】之【Bug】VMware 虚拟机开机 一直卡在黑屏左上角下划线闪烁界面

解决 参考&#xff1a; 解决Ubuntu20.04 开机黑屏光标闪烁进不去系统 Centos根目录100%解决思路 当前界面 ctrlaltf3-f6 暂时进入终端界面 df -h 查看发现根目录 磁盘空间已满 执行命令 查看当前目录占用内存明细 sudo du -h -x --max-depth1清理无用的大内存文件 或者安装…

RT-DETR融合YOLOv12中的R-ELAN结构

RT-DETR使用教程&#xff1a; RT-DETR使用教程 RT-DETR改进汇总贴&#xff1a;RT-DETR更新汇总贴 《YOLOv12: Attention-Centric Real-Time Object Detectors》 一、 模块介绍 论文链接&#xff1a;https://arxiv.org/abs/2502.12524 代码链接&#xff1a;https://gitcode.com…

【前端基础】Day 8 H5C3提高

目录 1. HTML5新特性 1.1 新增语义化标签 1.2 新增多媒体标签 1.3 新增input类型 1.4 新增表单属性 2. CSS3的新特性 2.1 新增选择器 2.1.1 属性选择器 2.1.2 结构伪类选择器 2.1.3 伪元素选择器&#xff08;重点&#xff09; 2.2 CSS3盒子模型 2.3 CSS3其他特性&a…

NL2SQL-基于Dify+阿里通义千问大模型,实现自然语音自动生产SQL语句

本文基于Dify阿里通义千问大模型&#xff0c;实现自然语音自动生产SQL语句功能&#xff0c;话不多说直接上效果图 我们可以试着问他几个问题 查询每个部门的员工数量SELECT d.dept_name, COUNT(e.emp_no) AS employee_count FROM employees e JOIN dept_emp de ON e.emp_no d…