实现@imput支持用户输入最多三位整数,最多一位小数的数值

实现@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]*" 配合软键盘优化。

这个方案可以确保用户只能输入合法的工时数据,适合用于填报系统、考勤系统等场景。

相关推荐
Su米苏16 分钟前
关于@vue-office/excel 渲染异常滚动失去内容
前端·vue.js·excel
灯澜忆梦18 分钟前
【基于GO的Web开发10】gin获取HTML-Form表单提交参数
前端·后端·golang·html·gin
撑伞的鱼99371 小时前
2026年前端AI编程工具评测:Figma 还原、组件复用、跨文件联动三项对比
前端·ai编程·figma·效率工具·ai编程工具
码视野1 小时前
基于 Vue3 + Element Plus 的【微短剧剧本智能创作与分镜生产协同系统】设计与实现(含PRD/三端源码/大屏)
前端·人工智能·vue3
zzzzzz3101 小时前
36K stars 的“酷炫组件”,到底该怎么用才不显得用力过猛?
前端·react.js·动效
2401_894915534 小时前
GEO 优化源码全解析:从搜索引擎到 AI 引擎的底层改写逻辑
java·服务器·前端·数据库·人工智能·分布式·搜索引擎
Profile排查笔记10 小时前
指纹浏览器哪个好?从 Profile、代理、权限和自动化能力判断是否适合
前端·人工智能·后端·自动化
lzhdim10 小时前
12、JavaScript常见的内存泄露问题 - JavaScript学习系列文章
开发语言·前端·javascript·学习·ecmascript
denggun1234510 小时前
yield
前端·数据库·python
前端snow10 小时前
ai agent -- prompt汇总
前端