Vue.js强制更新输入元素不起作用

4

我有一个输入元素,通过v-model绑定到一个项目值,我想限制用户输入只能输入0到10之间的数字值,我之前尝试过这个(add @input并检查输入值以保持在范围内)

我的代码如下:

<v-text-field @input="checkItem" v-model="item"></v-text-field>

checkItem(val) {
      if(parseInt(val) < 1) {
        this.item = 1;
      } else if(parseInt(val) >10) {
        this.item = 10;
      }
    }
问题 第一次我们输入了超出范围的数字后,该函数能够正常运行并将其保持在范围内,但当我们再次输入超出范围的数字时,元素没有更新,因为新的项目值与旧的项目值相同!为了解决这个问题,我试图使用forceUpdate和$forceUpdate()无效!!! 例如
  • 如果用户在输入框中输入范围内的任何内容,因为它在范围内,一切都正常;
  • 但是,如果用户输入0或任何超出范围的数字,在第一次项值改变为1时,如果值小于1,则如果再次键入任何负值,由于上次设置为1的项目值已经更改,因此在视图中不会发生任何变化,元素值也未被更新。
主要问题是如何强制Vue更新此输入字段的值?

你是否尝试使用“watch”方法来监听更改,而不是绑定到输入?在输入挂钩中修改模型数据并不是“v-model”的预期用法。 - rh16
如果你的意思是使用:value来绑定数据对象中的项目值,并在输入更改时在watch上更改该项目,那么我不得不说我以前尝试过,并且遇到了相同的问题(视图部分没有更新,因为值没有改变)。 - newvertex
3个回答

3
  <div><input type="number" v-model="item"></input></div>
</template>

<script>
export default {
  name: "ranges",

  data() {
    return {
      item: Number,
      error: String
    };
  },

  watch: {
    item(newVal, lastVal) {
      if (newVal > 10) this.item = 10
      if (newVal < 1) this.item = 1
    }
  }
};
</script>


在这里,您可以使用watcher进行验证。

谢谢您的回答,但我不想向用户显示消息,我想在用户输入时用正确的值替换用户输入的值(当前代码更新数据对象的值,但不更新组件的视图部分,因为数据对象上的值与之前相同,因此Vue认为没有发生更改)。 - newvertex
@Mojtaba,我刚刚更新了代码以实现你说的内容,请告诉我是否符合你的要求。 - mdiaz00147
完全正确,谢谢。 但是为什么有时第二个条件会出现问题并将其接受为零?! - newvertex
其实我以前从未使用过@input回调函数,可能存在问题,我建议在这种情况下最好使用watch方法或computed方法。 - mdiaz00147
主要的更新问题还没有解决!当我们第一次尝试在输入框中输入0时,它会被更新为1,但此后,在vue-devtool上的值是1,但在屏幕输入框元素上却显示为0!而且,如果我们输入最大值如1000,也会出现同样的问题。因此,我们需要重新渲染输入框元素以保持其更新。 - newvertex
你确定吗?看看这里,使用你给我的那些示例。https://codesandbox.io/s/2vl035z37y 我在那里测试过了,运行良好。 - mdiaz00147

1

当最终结果始终相同时,强制重新活化的唯一方法是重新渲染组件以通过更新其key来反映更改。

此处有参考链接。

我从mdiaz00147 fork了一个示例Vue项目, 并修改成了这个, 我认为它符合作者的意图。

解决方案代码修改自mdiaz00147的代码片段

<template>
  <div>
    <input :key="inputKey" v-model="item" @change="checkItem" />
  </div>
</template>

<script>
export default {
  name: "ranges",

  data() {
    return {
      item: null,
      inputKey: 0,
    };
  },

  methods: {
    checkItem() {
      if (parseInt(this.item) < 1) {
        this.item = 1;
      } else if (parseInt(this.item) > 10) {
        this.item = 10;
      }
      this.inputKey += 1;
    },
  },
};
</script>

这是有效的。唯一的缺点是当键改变时,输入会失去焦点。 - lhermann

0
我发现一个对我来说非常简单的解决方法,用于验证时的步骤如下:
  1. 首先将值设置为错误的未验证值,然后只在失焦或更改时设置它(不要在输入时设置,因为它会自动失焦)
  2. 然后运行验证逻辑并更新数据项(现在可以正常工作,因为它知道它已更改)
在代码中,你只需要改变这些部分:
checkItem(val) {
  this.item = val; // add this
  if(parseInt(val) < 1) {
    this.item = 1;
  } else if(parseInt(val) >10) {
    this.item = 10;
  }
}

只需确保在验证完成后,仅将值传递上去或者在验证参数之外的观察和计算中“使用”该值。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接