【问题标题】:What Vue does when input field's value does not match with binded "data"?当输入字段的值与绑定的“数据”不匹配时,Vue 会做什么?
【发布时间】:2020-12-22 09:31:12
【问题描述】:

我知道v-model,但首先我需要澄清v-bind 的行为。

考虑下面的例子:

<div id="app">
  <input 
    type="text" 
    :value="inputtedValue"
    @input="() => { onInput() }"
  >
</div>
export default {
  name: "App",
  data() {
    return {
      inputtedValue: ""
    }
  },
  methods: {
    onInput() {
      console.log(this.inputtedValue);
    }
  }
};

???? Fiddle

我对这个例子的假设正确吗?

  1. :value="inputtedValue" 不代表 ":value 属性值(重言式?)完全依赖于inputtedValue";可能会有所不同。
  2. 而是说“当inputtedValue更新时,:value属性值将被更新”,但是如果要在输入字段中输入新值,Vue不会知道

但最有趣的实验数据是:

  1. 如果inputtedValue没有改变,我们不能改变value属性值,即使它与inputtedValue不匹配。

假设我们想从输入中删除减号:

<div id="app">
  <input 
    type="text" 
    :value="inputtedValue"
    @input="$event => { onInput($event.target.value) }"
  >
</div>
export default {
  name: "App",
  data() {
    return {
      inputtedValue: ""
    }
  },
  methods: {
    onInput(rawValue) {
      
     if (rawValue.includes("-")) {
       this.inputtedValue = rawValue.replace("-", "");
     } else {
       this.inputtedValue = rawValue;
     }

     console.log(this.inputtedValue);
    }
  }
};

???? Fillde

如果输入减号,this.inputtedValue = rawValue.replace("-", ""); 不会改变现有的this.inputtedValue。所以我们又有this.inputtedValuevalue 属性的值差异:

我想要什么?

  1. 用户输入符号
  2. 如果符号有效 - 将其添加到 input 元素并发出 input 事件(对于组件)
  3. 如果符号无效 - 不要将其添加到 input 元素并且不要发出 input 事件(对于组件)

v-model 行为不同:

  1. 用户输入符号
  2. 绑定变量值变化

现在我们认为输入的值是无效的,我们可以改变绑定的值,vue 会改变输入的值。动作太多,而且新值和旧值无法比较。

【问题讨论】:

    标签: javascript vue.js


    【解决方案1】:

    为了防止不需要的字符出现在您的文本框中,即使输入,您确实需要使用@keydown 处理程序。您还可以使用带有 gettersetter 的计算属性来控制数据流,同时使用 v-model

    <input type="text" v-model="editableValue" @keydown="checkSymbol">
    
    export default {
      data: () => ({ inputtedValue: "" }),
      computed: {
        editableValue: {
          get: vm => vm.inputtedValue,
          set (rawValue) {
            this.inputtedValue = rawValue
            this.$emit("input", this.inputtedValue)
          }
        }
      },
      methods: {
        checkSymbol($event) {
          if ($event.key === "-") {
            $event.preventDefault();
          }
        }
      }
    }
    

    【讨论】:

    • 感谢您的回答。 “你的例子中遗漏了一个重要的成分”:对不起,我不明白这部分。我错过了什么?我绑定了value,是吗? “你需要从 $event 中捕获它”——我在第二个例子中做到了。还是@input="$event =&gt; { onInput($event.target.value) }" 错了?在第一个示例中,我们尚未捕获输入。
    • 我添加了第二个例子的模板部分。
    • 对,我现在已经从我的答案中删除了那部分
    • @TakesiTokugawaYD 我更新了 CodeSandbox 演示,增加了一些日志记录。事件排序为keydowninputkeyup。如果keydown 阻止默认操作,则input 根本不会触发
    • @TakesiTokugawaYD 一点问题都没有?
    猜你喜欢
    • 2018-09-12
    • 2020-09-26
    • 2011-11-27
    • 1970-01-01
    • 2017-09-28
    • 2021-11-06
    • 2017-03-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多