LoginSignup
9
6

More than 3 years have passed since last update.

[Vue.js]小数や整数しか入力できないinputタグのカスタムコンポーネント

Last updated at Posted at 2019-02-14

2020/06/01追記

[今度こそ完全に理解した]vueで数字しか入力できないinputタグのカスタムコンポーネントを作る
の方で諸問題に対応したコードを公開したのでそちらを参照して頂けると。。。

以前

vue.jsで「数字」しか入力できないinput要素を作る
という記事を書いた話の続き(?)で
今回は小数の場合の追加とカスタムコンポーネント化をしました

おさらい

htmlで

<input type="number">

って書くと
「0」「1」「2」「3」「4」「5」「6」「7」「8」「9」
の他に
「e」「.」「+」「-」なども入力できてしまう
都合が悪い時がある

答え

InputComponent.vue
<template>
  <div>
    <input
      type="text"
      ref="input"
      :value="innerValue"
      @input="validateInput($event.target.value)"
    >
  </div>
</template>

<script>
export default {
  name: 'InputComponent',
  props: ['value', 'type'],
  computed: {
    innerValue: {
      get() {
        return this.value;
      },
      set(val) {
        this.$refs.input.value = val; // 見た目に反映するため
        this.$emit('input', val);
      },
    },
  },
  methods: {
    validateInput(val) {
      switch (this.type) {
        case 'integer':
          this.innerValue = this.validateInteger(val);
          break;
        case 'decimal':
          this.innerValue = this.validateDecimal(val);
          break;
        default:
          this.innerValue = val;
          break;
      }
    },
    validateInteger(val) {
      // 数字以外を消す
      return val.replace(/\D/g, '');
    },
    validateDecimal(val) {
      // 小数のフォーマットに一致する部分を切り出して一致している部分のみで上書き
      // 末尾ドットは入力途中の過程で必要だから許可する ※1
      const result = val.match(/^(\d+)(\.\d*)?/u);
      return result ? result[0] : '';
    },
  },
  mounted() {
    this.validateInput(this.innerValue);
  },
};
</script>

使い方

Form.vue
<template>
  <form>
    <!-- 整数のみ -->
    <input-component
      v-model="valInteger"
      :type="`integer`"
    />

    <!-- 整数または小数のみ -->
    <input-component
      v-model="valDecimal"
      :type="`decimal`"
    />
  </form>
</template>
<script>
import InputComponent from '@/components/InputComponent';
export default {
  name: 'Form',
  components: {
    'input-component': InputComponent,
  },
  data() {
    return {
      valInteger: '',
      valDecimal: '',
    };
  },
}
</script>

※1解説

小数を検知する正規表現はこちらの記事を参考にカスタマイズしました
【Javascript】正規表現で整数と少数にマッチさせる。

整数部分と小数部分無制限にマッチさせる正規表現が
^([1-9]\d*|0)(\.\d+)?$
とありましたが

  • 整数部は\d+でいい気がするので改変
  • 末尾ドットを許可するために小数部は(\.\d*)へ改変
  • 最後に意図しない文字が入力されても「マッチしない」という結果ではなく「意図しない文字より前の部分が一致する」という結果にしたいので末尾の$を外す

結果
/^(\d+)(\.\d*)?/uに改変して使っています

/^(\d+)(\.)?(\d*)/u
の方が意味がわかりやすいかな

その他参考記事

https://qiita.com/ktkiyoshi/items/cbbb002a4fb9a0ff9a27
https://joe-noh.hatenablog.com/entry/2017/09/01/235943

正規表現の神様へ

だめじゃんこの正規表現って箇所ありましたらご指摘いただけると助かります

正規表現好きですが穴があることが稀によくあるので。。。。

9
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
6