You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue输入框金额格式化:显示格式化值但保留原始数值

解决方案

核心思路

不能直接用v-model绑定原始存储值,因为v-model是双向绑定会同步修改原始数据。需要将显示值和存储值分离:用独立变量维护输入框的格式化显示内容,输入时将内容还原为纯数字存入原始对象,同时更新显示值为格式化后的结果。

具体实现步骤

  1. 新增两个独立的响应式变量,用于绑定输入框的显示内容
  2. 编写格式化/反格式化工具函数:
    • 格式化函数:将纯数字转为带千分位、货币符号的字符串
    • 反格式化函数:将用户输入的格式化字符串还原为纯数字
  3. 拆分v-model为:value(绑定显示值)和@input(处理输入逻辑)
  4. 监听原始存储值的变化,同步更新显示值(应对初始赋值或外部修改场景)

完整代码示例

模板部分

<div class="budget info" :class="{ 'input-error': inputsValid.budget }">
  <label>Budget</label>
  <input 
    type="text" 
    :value="displayBudget"
    @input="handleBudgetInput"
  >
</div>

<div class="area info" :class="{ 'input-error': inputsValid.area }">
  <label>Area</label>
  <input 
    type="text" 
    :value="displayArea"
    @input="handleAreaInput"
  >
</div>

脚本部分

import { ref, watch } from 'vue'

const info = ref({
  budget: '',
  area: '',
})

// 维护输入框的显示值
const displayBudget = ref('$0.00')
const displayArea = ref('')

// 格式化工具:货币格式(千分位+美元符号)
const currencyFormatter = new Intl.NumberFormat('en-US', {
  style: 'currency', 
  currency: 'USD'
})
// 格式化工具:数字千分位分隔(用于面积)
const numberFormatter = new Intl.NumberFormat('en-US')

// 反格式化:提取纯数字
const unformatNumber = (str) => {
  if (!str) return ''
  // 移除所有非数字和小数点的字符
  const pureNum = str.replace(/[^0-9.]/g, '')
  // 处理多个小数点的情况
  return pureNum.indexOf('.') !== pureNum.lastIndexOf('.') 
    ? pureNum.slice(0, pureNum.indexOf('.')) + pureNum.slice(pureNum.indexOf('.'))
    : pureNum
}

// Budget输入处理
const handleBudgetInput = (e) => {
  const rawValue = unformatNumber(e.target.value)
  // 更新原始存储值
  info.value.budget = rawValue
  // 更新显示值:如果是空值显示$0.00,否则格式化
  displayBudget.value = rawValue ? currencyFormatter.format(rawValue) : '$0.00'
  // 验证逻辑
  inputsValid.budget = rawValue === ''
}

// Area输入处理
const handleAreaInput = (e) => {
  const rawValue = unformatNumber(e.target.value)
  // 更新原始存储值
  info.value.area = rawValue
  // 更新显示值:空值显示空,否则加千分位
  displayArea.value = rawValue ? numberFormatter.format(rawValue) : ''
  // 验证逻辑
  inputsValid.area = rawValue === ''
}

// 监听原始值变化,同步显示值(比如从后端加载数据时)
watch(() => info.value.budget, (newVal) => {
  displayBudget.value = newVal ? currencyFormatter.format(newVal) : '$0.00'
})

watch(() => info.value.area, (newVal) => {
  displayArea.value = newVal ? numberFormatter.format(newVal) : ''
})

// 初始化验证状态(根据原有逻辑调整)
const inputsValid = ref({
  budget: info.value.budget === '',
  area: info.value.area === ''
})

关键细节说明

  • 把Budget输入框的type="number"改为type="text":因为number类型输入框无法显示带货币符号、千分位的格式化字符串
  • 反格式化函数会过滤所有非数字和小数点的字符,确保存入info的是纯数字字符串
  • 通过watch监听info的原始值,确保外部修改原始数据时,输入框显示也会同步更新
  • 验证逻辑直接基于原始存储值判断,避免受格式化显示值的影响

内容的提问来源于stack exchange,提问作者Jose

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 14:20:23