news 2026/4/23 17:43:38

el-input只能输入数字且支持小数,精度为n(14,6)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
el-input只能输入数字且支持小数,精度为n(14,6)

方案一:自定义指令(推荐,可复用)

<template> <!-- 使用自定义指令,精度(14,6) --> <el-input v-model="decimalValue" v-decimal="{ maxInt: 14, maxDecimal: 6 }" placeholder="整数最多14位,小数最多6位" /> <!-- 可配置不同精度 --> <el-input v-model="priceValue" v-decimal="{ maxInt: 8, maxDecimal: 2 }" placeholder="价格(8,2)" /> </template> <script setup> import { ref } from 'vue' // 自定义指令 const vDecimal = { mounted(el, binding) { const input = el.querySelector('input') if (!input) return const config = { maxInt: binding.value?.maxInt || 14, // 最大整数位数 maxDecimal: binding.value?.maxDecimal || 6, // 最大小数位数 allowNegative: binding.value?.allowNegative ?? true, allowZeroStart: binding.value?.allowZeroStart ?? false } input.addEventListener('input', (e) => { handleDecimalInput(e.target, config) }) input.addEventListener('blur', (e) => { formatDecimalValue(e.target, config) }) } } // 处理输入 const handleDecimalInput = (input, config) => { let value = input.value // 允许的字符:数字、小数点、负号 const allowedChars = config.allowNegative ? /[0-9.-]/g : /[0-9.]/g const filtered = value.match(allowedChars)?.join('') || '' // 处理多个负号 let processedValue = filtered if (config.allowNegative) { const dashCount = (processedValue.match(/-/g) || []).length if (dashCount > 1) { processedValue = '-' + processedValue.replace(/-/g, '') } if (processedValue.includes('-') && processedValue.indexOf('-') > 0) { processedValue = processedValue.replace(/-/g, '') } } // 处理多个小数点 const parts = processedValue.split('.') if (parts.length > 2) { processedValue = parts[0] + '.' + parts.slice(1).join('') } // 拆分整数和小数部分 const [integerPart = '', decimalPart = ''] = processedValue.split('.') // 限制整数部分长度 const limitedInteger = integerPart.slice(0, config.maxInt) // 限制小数部分长度 const limitedDecimal = decimalPart.slice(0, config.maxDecimal) // 重新组合 let result = limitedInteger if (limitedDecimal) { result += '.' + limitedDecimal } // 不允许以0开头(除非是0.xxx) if (!config.allowZeroStart && result.length > 1 && result.startsWith('0') && !result.startsWith('0.')) { result = result.substring(1) } if (result !== value) { input.value = result input.dispatchEvent(new Event('input')) } } // 格式化值 const formatDecimalValue = (input, config) => { let value = input.value if (value === '' || value === '-' || value === '.') { input.value = '' return } // 处理以小数点开头的情况 if (value.startsWith('.')) { value = '0' + value } if (value.startsWith('-.')) { value = '-0' + value.slice(1) } // 确保小数位数为配置的位数 const parts = value.split('.') if (parts.length === 2) { parts[1] = parts[1].padEnd(config.maxDecimal, '0').slice(0, config.maxDecimal) value = parts.join('.') } input.value = value input.dispatchEvent(new Event('input')) } const decimalValue = ref('') const priceValue = ref('') </script>

方案二:封装为组件(功能完整)

<!-- DecimalInput.vue --> <template> <el-input v-model="displayValue" v-bind="$attrs" @input="handleInput" @blur="handleBlur" @keydown="handleKeydown" /> </template> <script setup> import { ref, computed, watch, nextTick } from 'vue' const props = defineProps({ modelValue: [String, Number], maxInt: { // 最大整数位数 type: Number, default: 14 }, maxDecimal: { // 最大小数位数 type: Number, default: 6 }, allowNegative: { type: Boolean, default: true }, integerOnly: { // 是否只允许整数 type: Boolean, default: false }, trimZero: { // 是否去除末尾的0 type: Boolean, default: false } }) const emit = defineEmits(['update:modelValue', 'change']) // 显示值 const displayValue = ref('') // 同步外部值 watch(() => props.modelValue, (val) => { if (val !== undefined && val !== null) { displayValue.value = val.toString() } }, { immediate: true }) // 处理输入 const handleInput = (value) => { if (value === '') { updateValue('') return } // 构建正则表达式 const pattern = props.allowNegative ? /^-?\d*\.?\d*$/ : /^\d*\.?\d*$/ if (!pattern.test(value)) { // 回退到上一次有效值 nextTick(() => { displayValue.value = props.modelValue?.toString() || '' }) return } // 检查长度限制 const parts = value.split('.') const integerPart = parts[0].replace('-', '') const decimalPart = parts[1] || '' // 验证整数部分长度 if (integerPart.length > props.maxInt) { const limitedInteger = integerPart.slice(0, props.maxInt) const limitedValue = (value.startsWith('-') ? '-' : '') + limitedInteger if (decimalPart) { displayValue.value = limitedValue + '.' + decimalPart } else { displayValue.value = limitedValue } updateValue(displayValue.value) return } // 验证小数部分长度 if (decimalPart.length > props.maxDecimal) { const limitedDecimal = decimalPart.slice(0, props.maxDecimal) displayValue.value = parts[0] + '.' + limitedDecimal updateValue(displayValue.value) return } // 如果设置为只允许整数,移除小数点 if (props.integerOnly && value.includes('.')) { displayValue.value = value.replace('.', '') updateValue(displayValue.value) return } updateValue(value) } // 处理键盘事件 const handleKeydown = (e) => { // 阻止非数字、小数点、负号、控制键的输入 const allowedKeys = [ 'Backspace', 'Delete', 'Tab', 'Escape', 'Enter', 'Home', 'End', 'ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown' ] if (allowedKeys.includes(e.key)) { return } // 允许的数字和小数点 if (/[0-9]/.test(e.key)) { return } // 允许小数点 if (e.key === '.' && !props.integerOnly) { const currentValue = displayValue.value if (!currentValue.includes('.')) { return } } // 允许负号 if (e.key === '-' && props.allowNegative) { const currentValue = displayValue.value if (!currentValue.includes('-')) { return } } e.preventDefault() } // 处理失去焦点 const handleBlur = () => { if (!displayValue.value || displayValue.value === '-' || displayValue.value === '.') { updateValue('') return } // 处理以小数点开头的情况 let value = displayValue.value if (value.startsWith('.')) { value = '0' + value } if (value.startsWith('-.')) { value = '-0' + value.slice(1) } // 补全小数位数 const parts = value.split('.') if (parts.length === 2) { if (props.trimZero) { // 去除末尾的0 parts[1] = parts[1].replace(/0+$/, '') if (parts[1] === '') { value = parts[0] } else { value = parts[0] + '.' + parts[1] } } else { // 补0到指定长度 parts[1] = parts[1].padEnd(props.maxDecimal, '0').slice(0, props.maxDecimal) value = parts.join('.') } } displayValue.value = value updateValue(value) } // 更新值 const updateValue = (value) => { emit('update:modelValue', value) emit('change', value) } </script>

使用封装组件

<template> <div class="form-container"> <!-- 精度(14,6) --> <el-form-item label="金额(14,6)"> <DecimalInput v-model="form.amount" :max-int="14" :max-decimal="6" placeholder="请输入金额,整数最多14位,小数最多6位" /> </el-form-item> <!-- 精度(8,2) --> <el-form-item label="单价(8,2)"> <DecimalInput v-model="form.price" :max-int="8" :max-decimal="2" placeholder="单价,保留2位小数" /> </el-form-item> <!-- 只允许整数 --> <el-form-item label="数量"> <DecimalInput v-model="form.quantity" :max-int="8" :integer-only="true" placeholder="请输入数量" /> </el-form-item> <!-- 不允许负数 --> <el-form-item label="百分比(0-100)"> <DecimalInput v-model="form.percentage" :max-int="3" :max-decimal="2" :allow-negative="false" placeholder="0-100,保留2位小数" /> </el-form-item> </div> </template> <script setup> import { reactive } from 'vue' import DecimalInput from './DecimalInput.vue' const form = reactive({ amount: '', price: '', quantity: '', percentage: '' }) </script>
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/23 15:47:34

Qwen2.5-7B教程:如何构建个性化推荐系统

Qwen2.5-7B教程&#xff1a;如何构建个性化推荐系统 1. 引言&#xff1a;为什么选择Qwen2.5-7B构建推荐系统&#xff1f; 在当前AI驱动的智能应用浪潮中&#xff0c;个性化推荐系统已成为电商、内容平台、社交网络等领域的核心竞争力。传统推荐算法&#xff08;如协同过滤、矩…

作者头像 李华
网站建设 2026/4/23 13:03:43

Qwen2.5-7B知识图谱:结构化知识增强

Qwen2.5-7B知识图谱&#xff1a;结构化知识增强 1. 技术背景与核心价值 1.1 大模型演进中的知识瓶颈 随着大语言模型&#xff08;LLM&#xff09;在自然语言理解、代码生成和多轮对话等任务中表现日益强大&#xff0c;传统“黑箱式”训练方式逐渐暴露出其局限性——缺乏对结…

作者头像 李华
网站建设 2026/4/23 11:37:09

Qwen2.5-7B财务预测模型:基于文本数据的分析

Qwen2.5-7B财务预测模型&#xff1a;基于文本数据的分析 1. 引言&#xff1a;大语言模型在金融领域的潜力 1.1 财务预测的新范式 传统财务预测依赖于结构化数据&#xff08;如财报、股价、交易量&#xff09;和统计建模方法&#xff08;如ARIMA、GARCH&#xff09;。然而&…

作者头像 李华
网站建设 2026/4/23 14:52:09

2024大模型趋势入门必看:Qwen2.5-7B开源+弹性GPU部署实战指南

2024大模型趋势入门必看&#xff1a;Qwen2.5-7B开源弹性GPU部署实战指南 1. 引言&#xff1a;为什么 Qwen2.5-7B 值得关注&#xff1f; 2024年&#xff0c;大语言模型&#xff08;LLM&#xff09;正从“参数竞赛”转向实用化落地与高效部署并重的新阶段。阿里云发布的 Qwen2.5…

作者头像 李华
网站建设 2026/4/23 16:11:51

图解说明ArduPilot如何通过BLHeli实现精准油门响应

ArduPilot 如何通过 BLHeli 实现毫秒级油门响应&#xff1f;一文讲透底层逻辑你有没有遇到过这种情况&#xff1a;遥控杆轻轻一推&#xff0c;无人机却“慢半拍”才开始上升&#xff1b;悬停时轻微抖动&#xff0c;像喝醉了一样&#xff1b;高速转弯时动力跟不上&#xff0c;差…

作者头像 李华
网站建设 2026/4/23 11:38:33

Qwen2.5-7B推理加速:SwiGLU激活函数优化实战

Qwen2.5-7B推理加速&#xff1a;SwiGLU激活函数优化实战 1. 引言&#xff1a;为何关注Qwen2.5-7B的推理性能&#xff1f; 1.1 大模型推理的现实挑战 随着大语言模型&#xff08;LLM&#xff09;在实际应用中的广泛部署&#xff0c;推理延迟和显存占用成为制约用户体验的关键…

作者头像 李华