#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);
}
}
};
Верна ли моя гипотеза об этом примере?
:value="inputtedValue"
не означает «:value
значение атрибута (тавтология?) полностью зависит отinputtedValue
«; это может отличаться.- Скорее это означает «При
inputtedValue
обновлении:value
значение атрибута будет обновлено», но если ввести новое значение в поле ввода, Vue не узнает об этом.
Но наиболее интересные экспериментальные данные:
- Если
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
атрибута:
Что я хочу вместо этого?
- Пользователь вводит символ
- Если символ допустим — добавьте его в
input
элемент и выдайтеinput
событие (для компонентов) - Если символы недопустимы — не добавляйте их в
input
элемент и не генерируйтеinput
событие (для компонентов)
v-model
поведение отличается:
- Пользователь вводит символ
- значение привязанной переменной изменяется
Теперь мы считаем введенное значение недопустимым, мы можем изменить привязанное значение, и 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();
}
}
}
}
Комментарии:
1. Спасибо за ответ. «В ваших примерах отсутствует важный компонент»: Извините, я не понял эту часть. Что я пропустил? Я привязал
value
, не так ли? «вам нужно записать это из $ event» — я сделал это во втором примере. Или@input="$event => { onInput($event.target.value) }"
это неправильно? В первом примере мы еще не фиксируем ввод.2. Я добавил шаблонную часть второго примера.
3. Хорошо, теперь я удалил эту часть из своего ответа
4. @TakesiTokugawaYD Я обновил демонстрационную версию CodeSandbox, добавив еще несколько записей. Порядок событий меняется
keydown
,input
keyup
. Еслиkeydown
предотвращает действие по умолчанию,input
вообще не запускается5. @TakesiTokugawaYD Вообще не проблема 😄