实现@imput支持用户输入最多三位整数,最多一位小数的数值
template 模板视图
html
<template>
<div>
<label for="work-hours">工时:</label>
<input
id="work-hours"
v-model="hours"
type="text"
placeholder="请输入工时(如:8.5)"
@input="handleInput"
@blur="handleBlur"
/>
<p>当前值:{{ hours }}</p>
</div>
</template>
script 脚本部分
js
import { ref } from 'vue'
// 使用字符串类型以便更好地控制输入
const hours = ref('')
// 处理输入事件
const handleInput = (event) => {
let value = event.target.value
// 只允许数字和一个小数点
const regex = /^\d{0,3}(.\d{0,1})?$/
if (regex.test(value) || value === '') {
hours.value = value
} else {
// 如果不符合规则,则截取到符合的部分
const cleaned = cleanInput(value)
hours.value = cleaned
// 可选:同步 DOM 值(防止视图不更新)
event.target.value = cleaned
}
}
// 辅助函数:清理非法输入
const cleanInput = (value) => {
// 移除非数字和非小数点字符(保留第一个小数点)
let cleaned = ''
let decimalFound = false
for (let char of value) {
if (/\d/.test(char)) {
// 检查是否超过三位整数部分
const parts = cleaned.split('.')
if (!decimalFound && parts[0].length >= 3) continue // 整数部分超限
if (decimalFound && parts.length > 1 && parts[1].length >= 1) continue // 小数部分超限
cleaned += char
} else if (char === '.' && !decimalFound) {
decimalFound = true
const parts = cleaned.split('.')
if (parts[0] === '') cleaned = '0' // 自动补零,如 .5 -> 0.5
cleaned += '.'
}
// 忽略其他字符
}
return cleaned
}
// 失焦时格式化最终值
const handleBlur = () => {
let val = hours.value
if (val === '.') {
hours.value = ''
return
}
// 去掉开头的多余 0,比如 007 -> 7
if (val.startsWith('0') && val !== '0' && !val.startsWith('0.')) {
const trimmed = val.replace(/^0+/, '')
hours.value = trimmed ? parseFloat(trimmed).toFixed(1).replace(/.?0+$/, '') : '0'
}
// 格式化显示(可选)
if (val.includes('.')) {
const [int, dec] = val.split('.')
hours.value = `${int}.${dec.slice(0, 1)}`
}
}
AI 生成
在 Vue 中,要实现一个输入框(<input>
)来限制用户只能输入最多三位整数位和最多一位小数位 的数值(即最大值为 999.9
),可以通过多种方式实现。以下是一个完整的解决方案,使用 Vue 3 的 Composition API 和 <script setup>
语法:
✅ 需求分析
- 允许输入:
0
,12
,123
,123.4
,.5
等。 - 不允许:
- 超过三位整数:如
1234
- 超过一位小数:如
12.34
- 非数字字符(除小数点外)
- 超过三位整数:如
- 实时校验并修正输入
✅ 示例代码(Vue 3 + Composition API)
vue
<template>
<div>
<label for="work-hours">工时:</label>
<input
id="work-hours"
v-model="hours"
type="text"
placeholder="请输入工时(如:8.5)"
@input="handleInput"
@blur="handleBlur"
/>
<p>当前值:{{ hours }}</p>
</div>
</template>
<script setup>
import { ref } from 'vue'
// 使用字符串类型以便更好地控制输入
const hours = ref('')
// 处理输入事件
const handleInput = (event) => {
let value = event.target.value
// 只允许数字和一个小数点
const regex = /^\d{0,3}(\.\d{0,1})?$/
if (regex.test(value) || value === '') {
hours.value = value
} else {
// 如果不符合规则,则截取到符合的部分
const cleaned = cleanInput(value)
hours.value = cleaned
// 可选:同步 DOM 值(防止视图不更新)
event.target.value = cleaned
}
}
// 辅助函数:清理非法输入
const cleanInput = (value) => {
// 移除非数字和非小数点字符(保留第一个小数点)
let cleaned = ''
let decimalFound = false
for (let char of value) {
if (/\d/.test(char)) {
// 检查是否超过三位整数部分
const parts = cleaned.split('.')
if (!decimalFound && parts[0].length >= 3) continue // 整数部分超限
if (decimalFound && parts.length > 1 && parts[1].length >= 1) continue // 小数部分超限
cleaned += char
} else if (char === '.' && !decimalFound) {
decimalFound = true
const parts = cleaned.split('.')
if (parts[0] === '') cleaned = '0' // 自动补零,如 .5 -> 0.5
cleaned += '.'
}
// 忽略其他字符
}
return cleaned
}
// 失焦时格式化最终值
const handleBlur = () => {
let val = hours.value
if (val === '.') {
hours.value = ''
return
}
// 去掉开头的多余 0,比如 007 -> 7
if (val.startsWith('0') && val !== '0' && !val.startsWith('0.')) {
const trimmed = val.replace(/^0+/, '')
hours.value = trimmed ? parseFloat(trimmed).toFixed(1).replace(/\.?0+$/, '') : '0'
}
// 格式化显示(可选)
if (val.includes('.')) {
const [int, dec] = val.split('.')
hours.value = `${int}.${dec.slice(0, 1)}`
}
}
</script>
<style scoped>
input {
padding: 8px;
font-size: 16px;
border: 1px solid #ccc;
border-radius: 4px;
}
</style>
🔍 功能说明
特性 | 说明 |
---|---|
v-model 绑定字符串 |
更容易处理中间状态(如正在输入 .5 ) |
正则 /^\d{0,3}(\.\d{0,1})?$/ |
保证不超过 3 位整数、1 位小数 |
@input 实时过滤 |
防止非法字符或超出长度输入 |
cleanInput() 函数 |
手动解析字符串,精确控制每一位输入 |
@blur 处理 |
输入完成时进行规范化 |
✅ 支持的输入示例
用户输入 | 实际结果 | 说明 |
---|---|---|
1 |
1 |
✅ 正常 |
123 |
123 |
✅ 最大整数 |
123.4 |
123.4 |
✅ 合法小数 |
123.45 |
123.4 |
❌ 第二位小数被截断 |
1234 |
123 |
❌ 第四位整数被忽略 |
.5 |
0.5 |
⚠️ 可自动补 0 或保留 .5 (本例中保留) |
abc12.3xyz |
12.3 |
✅ 非法字符被过滤 |
💡 进阶建议
- 若用于表单提交,建议在提交前再次校验
parseFloat(hours.value)
是否在0 ~ 999.9
范围内。 - 可改为
type="number"
并配合step="0.1"
,但对输入控制较弱,仍需 JS 辅助。 - 移动端可考虑使用
pattern="[0-9]*"
配合软键盘优化。
这个方案可以确保用户只能输入合法的工时数据,适合用于填报系统、考勤系统等场景。