简体   繁体   中英

What Vue does when input field's value does not match with binded “data”?

I know about v-model , but first I need to clarify v-bind behaviour.

Consider below example:

<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

Is my hypothesis about this example right?

  1. :value="inputtedValue" does not mean " :value attribute value (tautology?) is fully depends on inputtedValue "; it could differ.
  2. Rather it means "When inputtedValue updated, :value attribute value will be updated", but if to type new value to input field, Vue will not know about it.

But most interesting experimental data is:

  1. If inputtedValue has not been changed, we can not change the value attribute value even it does not match with inputtedValue .

Suppose we want to remove minus signs from input:

<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

If to input minus, this.inputtedValue = rawValue.replace("-", ""); will not change the existing this.inputtedValue . So we have this.inputtedValue and value attribute's value discrepancy again:

在此处输入图片说明

What I want instead?

  1. User inputs the symbol
  2. If symbol is valid - add it to input element and emit input event (for components)
  3. If symbols is invalid - do not add it to input element and don't not emit input event (for components)

v-model behavior is differ:

  1. User inputs the symbol
  2. binded variable value changes

Now we consider inputted value as invalid, we can change the binded value and vue will change the input's value. Too much movements, and also, we can't compare new value and previous.

In order to prevent unwanted characters appearing in your text box, even if typed, you really need to use a @keydown handler. You can also use a computed property with getter and setter to control the data-flow while using 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();
      }
    }
  }
}

编辑youthful-fog-5bmin

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM