当前位置: 首页 > news >正文

el-Input输入数字自动转千分位进行展示

el-Input输入数字自动转千分位进行展示,存储值不变

子组件:

<template><el-input ref="inputRef" :disabled="disabled" clearable v-model="displayValue" v-bind="$attrs" @input="handleInput" @focus="handleFocus" @blur="handleBlur" @change="handleChange" @keydown="handleKeyDown" @compositionstart="handleCompositionStart" @compositionend="handleCompositionEnd"></el-input>
</template><script>
export default {name: 'AmountInput',props: {value: {type: [Number, String],default: null,},disabled: {type: Boolean,default: false,},// 新增精度控制属性precision: {type: Number,default: 2,},// 新增:是否启用大数模式(字符串处理)bigNumber: {type: Boolean,default: true,},},data() {return {displayValue: '',internalValue: null,isFocused: false,lastValidValue: null,isComposing: false, // 标记是否在中文输入法组合输入中};},watch: {value: {immediate: true,handler(newVal) {const parsed = this.parseInputValue(newVal);if (parsed !== this.internalValue) {this.internalValue = parsed;this.formatDisplayValue();}},},},mounted() {this.internalValue = this.parseInputValue(this.value);this.formatDisplayValue();},methods: {// 确保转换为字符串处理safeToString(value) {if (value === null || value === undefined) return '';return String(value);},// 处理中文输入法开始handleCompositionStart() {this.isComposing = true;},// 处理中文输入法结束handleCompositionEnd(e) {this.isComposing = false;this.handleInput(e.target.value);},// 处理大数字符串processBigNumber(numStr) {console.log(numStr, 'numStr');if (!numStr) return '';// 移除所有非数字字符(保留负号和小数点)let cleaned = numStr.replace(/[^\d.-]/g, '');// 分离符号、整数和小数部分const isNegative = cleaned.startsWith('-');if (isNegative) cleaned = cleaned.substring(1);const parts = cleaned.split('.');let integerPart = parts[0].replace(/^0+/, '') || '0';let decimalPart = parts.length > 1 ? parts[1] : '';// 截断小数部分if (decimalPart.length > this.precision) {decimalPart = decimalPart.substring(0, this.precision);}// 添加千分位integerPart = integerPart.replace(/\B(?=(\d{3})+(?!\d))/g, ',');// 重新组合return (isNegative ? '-' : '') + integerPart + (decimalPart ? `.${decimalPart}` : '');},formatDisplayValue() {if (this.isFocused) {this.displayValue = this.internalValue !== null ? this.safeToString(this.internalValue) : '';} else {this.displayValue = this.formatNumber(this.internalValue);}},parseInputValue(value) {if (value === '' || value === null || value === undefined) return null;const numStr = this.safeToString(value).replace(/,/g, '').replace(/[^\d.-]/g, '');if (numStr === '-' || numStr === '.') return null;// 处理大数字符串if (numStr.length > 15) {return numStr; // 作为字符串返回,避免精度丢失}const num = Number(numStr);return isNaN(num) ? null : num;},// 修复科学计数法转换convertFromScientificNotation(num) {if (num === null || num === undefined) return null;// 如果是字符串形式的科学计数法if (typeof num === 'string' && num.includes('e')) {try {return Number(num).toString();} catch {return num;}}// 如果是数值型的科学计数法if (typeof num === 'number' && num.toString().includes('e')) {return num.toLocaleString('fullwide', { useGrouping: false });}return num.toString();},// 增强的数字格式化方法formatNumber(value) {if (value === null || value === undefined) return '';const numStr = this.safeToString(value);const isNegative = numStr.startsWith('-');const cleanStr = isNegative ? numStr.substring(1) : numStr;const parts = cleanStr.split('.');let integerPart = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ',');let decimalPart = parts.length > 1 ? parts[1].substring(0, this.precision) : '';return (isNegative ? '-' : '') + integerPart + (decimalPart ? `.${decimalPart}` : '');},validateInput(value) {if (value === '' || value === null) return true;return new RegExp(`^-?\\d*\\.?\\d{0,${this.precision}}$`).test(value);},handleInput(value) {if (this.isComposing) return; // 中文输入法组合期间不处理const strValue = this.safeToString(value);const filtered = strValue.replace(/[^\d.-]/g, '');// 处理多个小数点const decimalParts = filtered.split('.');let cleanedValue = decimalParts[0];if (decimalParts.length > 1) {cleanedValue += '.' + decimalParts.slice(1).join('').substring(0, this.precision);}// 处理负号if (cleanedValue.includes('-')) {cleanedValue = '-' + cleanedValue.replace(/-/g, '');}if (cleanedValue !== this.displayValue) {this.displayValue = cleanedValue;}const parsed = this.parseInputValue(cleanedValue);this.internalValue = parsed;this.lastValidValue = cleanedValue;this.$emit('input', parsed);},handleFocus() {this.isFocused = true;this.formatDisplayValue();this.$emit('focus');},handleBlur() {this.isFocused = false;const parsed = this.parseInputValue(this.displayValue);this.internalValue = parsed;this.formatDisplayValue();this.$emit('blur');this.$emit('change', parsed);},handleKeyDown(e) {const allowedKeys = [8,9,37,39,46,35,36, // 特殊键...(e.ctrlKey ? [65, 67, 86, 88] : []), // Ctrl组合键];if (/\d/.test(e.key) || allowedKeys.includes(e.keyCode) || (e.key === '.' && !this.displayValue.includes('.')) || (e.key === '-' && !this.displayValue.includes('-') && (this.displayValue === '' || e.target.selectionStart === 0))) return;e.preventDefault();},},
};
</script>

父组件

<currency-input :value="addFormData.advancePaymentAmt" big-number :precision="2" @input="handleAmountInput($event, 'advancePaymentAmt')"></currency-input>
function handleAmountInput(data: any, field: string, type?: string, cIndex?: number) {// if (type == 'navItem_total' || type == 'navItem') {// 	state.formData.prodNavs.forEach((fItem: any, fIndex: number) => {// 		if (fIndex == cIndex) fItem[field] = data;// 	});// } else {// 	state.formData[field] = data;// }state.formData[field] = data;
}

相关文章:

  • LeetCode 1482. 制作 m 束花所需的最少天数
  • 机器学习-入门-线性模型(2)
  • 【时间之外】软件管理如何避免人浮于事
  • Fiddler+Yakit实现手机流量抓包和小程序抓包
  • Nacos 3.0 上线 MCP Registry,支持 MCP 服务注册到发现全流程管理
  • Android平台Unity引擎的Mono JIT机制分析
  • Android WebRTC回声消除
  • 向量数据库Milvus的部署与使用
  • quickbi finebi 测评(案例讲解)
  • OpenCV 图形API(70)图像与通道拼接函数-----创建一个图像或矩阵(GMat)的副本的操作函数copy()
  • 应用在通信网络设备的爱普生晶振SG2016CBN
  • DeepSeek创始人梁文峰是个什么样的人?
  • Linux调试器 - gdb使用指南
  • C#/.NET/.NET Core技术前沿周刊 | 第 36 期(2025年4.21-4.27)
  • GRPO vs SFT:强化学习提升大模型多模态推理泛化能力的原因研究
  • 关于windows API 的键鼠可控可测
  • Ocelot的应用案例
  • JDBC之Blob类型使用的实现
  • [特殊字符] 基于Docker部署Nacos注册中心及微服务注册发现详解(含MySQL持久化配置)
  • Mariadb 防火墙服务器和端口:mysql | 3306
  • 王毅:妥协退缩只会让霸凌者得寸进尺
  • 民航局答澎湃:督促各单位进一步完善航班大面积延误和大面积备降应急处置预案
  • 子公司神州信息十年来首次亏损,神州控股遭国有股东广州城投派驻董事问责
  • 今年一季度全国结婚登记181万对,较去年同期减少15.9万对
  • 魏晓栋已任上海崇明区委常委、组织部部长
  • 吉林建筑大学党委原书记崔征接受纪律审查和监察调查