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

如何格式化Vuex绑定的v-model值,提交前移除格式并解决删除键触发问题?

解决Vuex绑定时间格式输入框时的实时更新问题

看起来你遇到的核心问题是v-model的实时触发机制——每次按键(包括退格、删除)都会调用计算属性的set方法,而且你的set方法还有个关键bug:你在解析时间的时候误用了Store里的旧值this.$store.state.athlete.swimFtp,而不是用户当前输入的value,这会直接导致计算结果完全错误!先把这个bug修复,再解决触发时机的问题。

下面给你几个实用的解决方案:

方案1:用lazy修饰符延迟更新(最简单高效)

Vuetify的v-text-field支持Vue原生的v-model.lazy修饰符,它会在输入框失去焦点或者用户按下回车键时才更新绑定值,完美避开了每次按键都触发set的问题。

修改后的输入框代码:

<v-text-field 
  :label="$vuetify.t('$vuetify.swimFtp')" 
  :hint="$vuetify.t('$vuetify.swimFtp')" 
  mask="time-with-seconds" 
  v-model.lazy="swimFtp" 
  required
>
</v-text-field>

修正后的计算属性set方法:

set (value) {
  // 用用户输入的value解析,而不是Store旧值
  const [hours, mins, secs] = value.split(':').map(Number);
  const totalSeconds = hours * 3600 + mins * 60 + secs;
  this.$store.commit('updateSwimFtp', totalSeconds);
}

这个方案改动最小,完全匹配你的需求:只有用户确认输入(回车或失焦)时才更新Store。

方案2:手动绑定值+监听回车事件(更可控)

如果你想严格限制只有按下回车键才提交,可以放弃v-model,手动绑定显示值,用临时变量存储用户输入,再监听回车事件触发提交:

组件模板:

<v-text-field 
  :label="$vuetify.t('$vuetify.swimFtp')" 
  :hint="$vuetify.t('$vuetify.swimFtp')" 
  mask="time-with-seconds" 
  :value="formattedSwimFtp"
  @input="updateTempValue"
  @keydown.enter="submitToStore"
  required
>
</v-text-field>

组件脚本:

data() {
  return {
    tempInput: '' // 临时存储用户输入的时间字符串
  }
},
computed: {
  athlete() {
    return this.$store.state.athlete
  },
  formattedSwimFtp() {
    // 和原来的get方法一致,格式化Store中的秒数
    const date = new Date(null);
    date.setSeconds(this.athlete.swimFtp);
    return date.toISOString().substr(11, 8);
  }
},
methods: {
  updateTempValue(value) {
    // 实时同步用户输入到临时变量
    this.tempInput = value;
  },
  submitToStore() {
    // 回车时解析并提交到Store
    const [hours, mins, secs] = this.tempInput.split(':').map(Number);
    const totalSeconds = hours * 3600 + mins * 60 + secs;
    this.$store.commit('updateSwimFtp', totalSeconds);
  }
}

这个方案灵活性更高,你还可以额外添加一个“保存”按钮,把submitToStore绑定到按钮的点击事件上,给用户多一种提交选择。

方案3:优化计算属性的set方法(实时更新但避免错误)

如果你希望保持实时更新,但不想因为输入过程中的不完整格式(比如退格后输入未完成)导致错误值存入Store,可以在set方法里添加格式校验:

set (value) {
  // 校验输入是否符合##:##:##的格式
  const validTimeRegex = /^\d{2}:\d{2}:\d{2}$/;
  if (!validTimeRegex.test(value)) {
    // 格式不合法时不更新Store
    return;
  }
  const [hours, mins, secs] = value.split(':').map(Number);
  const totalSeconds = hours * 3600 + mins * 60 + secs;
  this.$store.commit('updateSwimFtp', totalSeconds);
}

这样即使用户在输入过程中触发了set,只要格式不完整,就不会把错误值写入Store。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.12 04:46:04