Что делает Vue, когда значение поля ввода не совпадает со связанными «данными»?

#javascript #vue.js

#javascript #vue.js

Вопрос:

Я знаю о 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);
    }
  }
};
  

🌎 Скрипка

Верна ли моя гипотеза об этом примере?

  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);
    }
  }
};
  

🌎 Заполнение

Если ввести минус, this.inputtedValue = rawValue.replace("-", ""); существующее значение не изменится this.inputtedValue . Итак, мы снова имеем несоответствие значений this.inputtedValue и value атрибута:

введите описание изображения здесь

Что я хочу вместо этого?

  1. Пользователь вводит символ
  2. Если символ допустим — добавьте его в input элемент и выдайте input событие (для компонентов)
  3. Если символы недопустимы — не добавляйте их в input элемент и не генерируйте input событие (для компонентов)

v-model поведение отличается:

  1. Пользователь вводит символ
  2. значение привязанной переменной изменяется

Теперь мы считаем введенное значение недопустимым, мы можем изменить привязанное значение, и vue изменит значение ввода. Слишком много движений, а также мы не можем сравнить новое значение и предыдущее.

Ответ №1:

Чтобы предотвратить появление нежелательных символов в вашем текстовом поле, даже если оно введено, вам действительно нужно использовать @keydown обработчик. Вы также можете использовать вычисляемое свойство с помощью getter и setter для управления потоком данных при использовании 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();
      }
    }
  }
}
  

Редактировать youthfull-fog-5bmin

Комментарии:

1. Спасибо за ответ. «В ваших примерах отсутствует важный компонент»: Извините, я не понял эту часть. Что я пропустил? Я привязал value , не так ли? «вам нужно записать это из $ event» — я сделал это во втором примере. Или @input="$event => { onInput($event.target.value) }" это неправильно? В первом примере мы еще не фиксируем ввод.

2. Я добавил шаблонную часть второго примера.

3. Хорошо, теперь я удалил эту часть из своего ответа

4. @TakesiTokugawaYD Я обновил демонстрационную версию CodeSandbox, добавив еще несколько записей. Порядок событий меняется keydown , input keyup . Если keydown предотвращает действие по умолчанию, input вообще не запускается

5. @TakesiTokugawaYD Вообще не проблема 😄