LoginSignup
3
4

More than 3 years have passed since last update.

【Vue.js】動的に数が変わる複数フォームの入力バインディング

Posted at

概要

フォームが複数ある場合に、入力バインディングする方法をまとめました。
基本的な内容ですが、備忘録も兼ねて初心者の方向けに書きたいと思います。

課題

例えば、フォームの数が固定されている場合は、各フォームに対応する分だけdataオブジェクトにプロパティを用意することで実装できます。
しかし、フォーム数が動的に変わる場合は、フォーム数に応じてdataオブジェクトにプロパティを追加する必要があるので面倒です。

また、プロパティ数が多いのは見栄えが悪いです。

フォーム数が固定されている場合
<template>
  <div>
    <!-- ループ数固定でv-forを使った場合 -->
    <div v-for="n in 3" :key="n">
      <input type="checkbox" :value="n" v-model="$data[`hoge${n}`]" />
      チェックボックス{{ n }}
    </div>

  <!-- べた書きした場合 -->
    <div>
      <input type="checkbox" value="4" v-model="hoge4" />
      チェックボックス4
    </div>
    <div>
      <input type="checkbox" value="5" v-model="hoge5" />
      チェックボックス5
    </div>
    <div>
      <input type="checkbox" value="6" v-model="hoge6" />
      チェックボックス6
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      hoge1: undefined,
      hoge2: undefined,
      hoge3: undefined,
      hoge4: undefined,
      hoge5: undefined,
      hoge6: undefined
    }
  }
}
</script>

解決方法

解決法としては、dataオブジェクトに一つのプロパティを用意し、配列の要素として入力バインディングしていきます。

チェックボックスの場合

dataオブジェクトのプロパティとしてhogeを用意し、初期値を配列にしておきます。
v-modelにはhogeを指定します。

<template>
  <div>
    <!-- loopの値によってループ数が変動 -->
    <div v-for="n in loop" :key="n">
      <input type="checkbox" v-model="hoge" />
      チェックボックス{{ n }}
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      hoge: [], // チェックを付けるごとに順に要素が追加される。(例)[1,3]
      loop: 3
    }
  }
}
</script>

ラジオボタンの場合

dataオブジェクトのプロパティとしてhogeを用意し、v-modelにはhoge[n - 1]を指定します。
配列の要素ごとにフォームを対応付けます。

<template>
  <div>
    <!-- loopの値によってループ数が変動 -->
    <div v-for="n in loop" :key="n">
      ラジオボタン{{ n }}
      <input type="radio" :name="'name' + n" value="A" v-model="hoge[n - 1]" />A
      <input type="radio" :name="'name' + n" value="B" v-model="hoge[n - 1]" />B
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      hoge: [], //(例)上から順にフォームに「A」「B」「A」を選択すると、["A","B","A"]
      loop: 3
    }
  }
}
</script>

テキストフィールドの場合

dataオブジェクトのプロパティとしてhogeを用意し、v-modelにはhoge[n - 1]を指定します。
配列の要素ごとにフォームを対応付けます。

<template>
  <div>
    <!-- loopの値によってループ数が変動 -->
    <div v-for="n in loop" :key="n">
      <input type="checkbox" v-model="hoge[n - 1]" />
      チェックボックス{{ n }}
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      hoge: [], // (例)上から順にフォームに「A」「B」「C」と入力すると、["A","B","C"]
      loop: 3
    }
  }
}
</script>

セレクトボックスの場合

dataオブジェクトのプロパティとしてhogeを用意し、v-modelにはhoge[n - 1]を指定します。
配列の要素ごとにフォームを対応付けます。

<template>
  <div>
    <!-- loopの値によってループ数が変動 -->
    <div v-for="n in loop" :key="n">
      セレクトボックス{{ n }}
      <select v-model="hoge[n - 1]">
        <option value="A">A</option>
        <option value="B">B</option>
        <option value="C">C</option>
      </select>
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      hoge: [], //(例)上から順に「A」「B」「C」を選択すると、["A","B","C"]
      loop: 3
    }
  }
}
</script>

まとめ

プロパティを一つ一つ用意するのか、まとめられるところは配列としてまとめるのか、使い分けが大事だと思います。
今回は配列にまとめる方法を書きました。
誰かの参考になれば幸いです。

3
4
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
3
4