Vueで数値 (Number) input の Atomic Componentを作成する方法

Vue_NumerInput

こんにちはフロントエンドエンジニアのまさにょんです!

今回は、Vueで数値 (Number) input の Atomic Componentを作成する方法について解説していきます。

Vueで数値(Number)input・Atomic Componentを作成する方法

数値 (Number) input・Component の要件定義

今回、作成する数値 (Number) input・Component の要件定義をまとめると、次のとおりです。

  1. 最小値と最大値をPropsで受け取れるように設定する。
  2. Defaultの最小値は0, 最大値は100にする。
  3. 設定された最小値より小さい数値や、最大値より大きい数値は入力できない。
  4. 初期値を設定できる。
  5. Inputなので、PropsでDisabled設定もできる。
  6. 左右に、プラスボタンとマイナスボタンがあり、それで数値の増減を設定できる。

数値 (Number) input・Component の SampleCode

<template>
  <div>
    <div class="number_input_wrapper">
      <!-- Minus_Icon_Btn -->
      <button @click="decrement" class="icon_btn">
        <img src="~/assets/image/icon/icon_minus.svg" alt="Minus Button" />
      </button>
      <input
        type="number"
        id="number-input"
        v-model="inputValue"
        @input="handleInput"
        :min="minValue"
        :max="maxValue"
        :disabled="isDisabled"
        class="custom-number-input"
      />
      <!-- Plus_Icon_Btn -->
      <button @click="increment" class="icon_btn">
        <img src="~/assets/image/icon/icon_plus.svg" alt="Plus Button" />
      </button>
    </div>
  </div>
</template>
<script>
export default {
  name: "NumberInput",
  components: {},
  props: {
    labelVal: {
      type: String,
      default: "数値入力:",
    },
    // 初期値
    initNumValue: {
      type: Number,
      default: 0,
    },
    // 最小値: 制約
    min: {
      type: Number,
      default: 0,
    },
    // 最大値: 制約
    max: {
      type: Number,
      default: 100,
    },
    // 入力フォーム無効化: Disabled
    disabled: {
      type: Boolean,
      default: false,
    },
    // Customize_Style
    numInputStyle: {
      type: Object,
      default: () => {
        return {};
      },
    },
  },
  data() {
    return {
      inputValue: this.initNumValue,
      minValue: this.min,
      maxValue: this.max,
    };
  },
  computed: {
    isDisabled() {
      return this.disabled;
    },
  },
  watch: {},
  methods: {
    // NumberInputの値が変更された時の処理
    handleInput(event) {
      const val = event.target.value;
      if (this.maxValue < val) {
        this.inputValue = this.maxValue;
      } else if (val < this.minValue) {
        this.inputValue = this.minValue;
      } else {
        this.inputValue = val;
      }
    },
    increment() {
      // 最大値まで
      if (this.inputValue < this.maxValue) {
        this.inputValue++;
      }
    },
    decrement() {
      // 最小値まで
      if (this.minValue < this.inputValue) {
        this.inputValue--;
      }
    },
  },
  created() {},
  mounted() {},
};
</script>
<style scoped>
/* Input_Number のデフォルトのスタイルを無効にするためのスタイル定義 */
input[type="number"]::-webkit-outer-spin-button,
input[type="number"]::-webkit-inner-spin-button {
  /* Chrome、Safari対応 */
  -webkit-appearance: none;
  /* FireFox対応 */
  -moz-appearance: textfield;
  margin: 0;
}
/* FlexBox */
.number_input_wrapper {
  display: inline-flex;
  align-items: center;
  align-content: center;
  flex-direction: row;
  flex-wrap: nowrap;
  gap: 5px;
}
/* NumberInput_Style_Custom */
.custom-number-input {
  text-align: center;
  border: 2px solid #ccc9c9;
  border-radius: 8px;
}
</style>

SVGのアイコン素材について

SVGのアイコン素材については、以前の記事で取得する方法などを紹介しています。

JavaScript書籍 Ver. 中級-上級者向け

JavaScript書籍 Ver. 初級者向け

Twitterやってます!Follow Me!

神聖グンマー帝国の逆襲🔥

神聖グンマー帝国の科学は、世界一ぃぃぃぃぃぃ!!!!!

最近の投稿