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

Vue中v-model与@keydown同元素时数据更新延迟问题咨询

Vue中v-model与keydown事件不同步问题的原理与解决

原理:事件触发顺序导致的延迟

keydown事件是在键盘按下瞬间触发的,此时浏览器还没来得及更新输入框的DOM值,而v-model的同步逻辑依赖输入框的DOM值变化(基于input/change等事件)。所以当keydown事件执行时,v-model绑定的ticker数据还没同步到最新输入内容,自然会少最后一个字符。

举个例子:输入"something"的最后一个"g"时,keydown先触发,此时输入框的实际值还停留在"somethin",v-model还没把新的"g"同步到ticker里,所以打印出来的就是少一个字符的结果。

解决办法

1. 替换keydown为input事件

input事件是在输入框内容更新完成后触发的,刚好能和v-model的同步节奏匹配,直接修改事件绑定即可:

<input
  v-model="ticker"
  @keydown.enter="addClick($event)"
  @input="getNames"
>

这样每次输入内容变化时,getNames拿到的ticker都是最新的。

2. 在keydown中直接取输入框实时值

如果必须保留keydown事件,可以通过事件对象直接获取输入框当前的DOM值,跳过v-model的同步延迟:

<input
  v-model="ticker"
  @keydown.enter="addClick($event)"
  @keydown="getNames($event)"
>
getNames(event) {
  // 直接从输入框DOM元素拿最新值
  const currentVal = event.target.value;
  console.log(currentVal);
  let filtered = this.coinNames.filter(item => item.toUpperCase().startsWith(currentVal.toUpperCase()))
  console.log(filtered);
  return filtered;
}

3. 用nextTick/setTimeout延迟执行

利用JavaScript的事件循环机制,让代码在DOM更新(v-model同步完成)后再执行:

方式一:Vue的$nextTick

getNames() {
  this.$nextTick(() => {
    console.log(this.ticker);
    let filtered = this.coinNames.filter(item => item.toUpperCase().startsWith(this.ticker.toUpperCase()))
    console.log(filtered);
    return filtered;
  });
}

方式二:setTimeout(0延迟即可)

getNames() {
  setTimeout(() => {
    console.log(this.ticker);
    let filtered = this.coinNames.filter(item => item.toUpperCase().startsWith(this.ticker.toUpperCase()))
    console.log(filtered);
    return filtered;
  }, 0);
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 16:15:35