Vue контролируемые входы - PullRequest
1 голос
/ 16 марта 2019

Я бы хотел, чтобы ввод текста принимал только последовательность чисел.Любой другой символ должен игнорироваться молча.Вот упрощенная версия моего компонента:

<template>
  <div id="app">
    <input :value="tel" @input="setTel" placeholder="only numbers" />
    <p>{{ tel }}</p>
  </div>
</template>

<script>
export default {
  name: "App",
  data: () => ({
    tel: "1234"
  }),

  methods: {
    setTel(v) {
      const val = v.target.value.replace(/[^0-9]/g, "");
      this.tel = val;
      /*this.tel = v.target.value = v.target.value.replace(/[^0-9]/g, "");*/
    }
  }
};
</script>

В React есть концепция контролируемых компонентов , но я не могу показаться похожим в Vue.

Обходной путь, который я нашел (который вы можете увидеть в комментариях), состоит в том, чтобы вручную изменить значение элемента ввода, но это отчасти побеждает цель использования Vue.

Я также пытался использовать v-model,но проблема остается.

codesandbox.

Ответы [ 4 ]

2 голосов
/ 16 марта 2019
<template>
  <div id="app">
    <input v-model="tel" v-on:keyup="setTel" placeholder="only numbers" />
    <p>{{ tel }}</p>
  </div>
</template>

<script>
export default {
  name: "App",
  data: () => ({
    tel: "1234"
  }),

  methods: {
    setTel(v) {
      const val = v.target.value.replace(/[^0-9]/g, "");
      this.tel = val;
      /*this.tel = v.target.value = v.target.value.replace(/[^0-9]/g, "");*/
    }
  }
};
</script>

Я посмотрел на вашу песочницу и внес несколько изменений. Пожалуйста, проверьте, хотите ли вы, это представление обновлено.

2 голосов
/ 16 марта 2019

хорошо, вы можете использовать <input type=number..., как все, что здесь сказано, но если вы хотите обрабатывать вручную, то вы можете изменить свой el.target.value в обработчике, например,

<template>
  <div id="app">
    <input
      :value="tel"
      @input="setTel"
      placeholder="0"
    />
    <p>{{ tel }}</p>
  </div>
</template>

<script>
export default {
  name: "App",
  data: () => ({
    tel: "1234"
  }),

  methods: {
    setTel(v) {
      v.target.value = v.target.value.replace(/[^0-9]/g, "");
      this.tel = v.target.value
      /*this.tel = v.target.value = v.target.value.replace(/[^0-9]/g, "");*/
    }
  }
};
</script>

и для части, в которой vue показывает текст на входе, потому что, когда вы назначаете то же значение после замены текста, vue не обновляет состояние этого конкретного элемента, чтобы избежать дополнительной визуализации

1 голос
/ 17 марта 2019

Вместо обработки keyup (что позволило бы клавише достичь ввода), вы должны обработать keydown.Обработчик должен вызвать event.preventDefault() и event.stopPropagation(), чтобы игнорировать ключ:

// ignore non-numeric keys
if (!/\d/.test(v.key)) {
  v.preventDefault()
  v.stopPropagation()
  return false
}

Ввод должен позволять мета-ключам (например, разрешать * 1012)* copy-paste или delete ):

// allow all meta keys (including Backspace) to pass through
if (v.metaKey || /(Backspace|Meta)/g.test(v.key)) {
  console.log('ignoring', v.key)
  return
}

Кроме того, этот вход должен обрабатывать событие input для фильтрации вставленных копий значений.

// template
<input v-model="tel" @input="onInput" v-on:keydown="setTel" />

// script
onInput(e) {
  if (e.inputType !== 'insertText' && /[^0-9]/g.test(e.target.value)) {
    const val = e.target.value.replace(/[^0-9]/g, "");
    this.tel = val;
    e.preventDefault()
    e.stopPropagation()
    return false
  }
}

демо

0 голосов
/ 16 марта 2019

Есть пара вещей, которые вы можете сделать:

  • установить тип входа на число <input type=number. Это заблокирует пользователя от ввода любого символа, кроме цифры. Это обрабатывается браузером.
  • Вы можете использовать v-model, а также добавить прослушиватель @change, чтобы проверить значение и соответственно изменить модель. Узел, в котором вы можете добавить модификатор number в модель, чтобы vue приводил ввод к числу
  • использовать рамки проверки, такие как vuelidate
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...