親バカエンジニアのナレッジ帳

webのエンジニアをやっており、日頃の開発で詰まったことや書き残しておきたいことを載せています。

Vue.jsで配列の値をAPIでPOSTする方法


値を配列でPOST

フォームでPOSTする項目数が決まっていない時、配列にして値をPOSTしたい場面があると思います。
例えばチェックボックスなんかは1つのnameに対して値の数は決まっていないものです。
また、テキストフォームであっても、入力フォームを追加して不特定多数の値をPOSTする場面があるでしょう。

今回はそのような場合のPOST方法についてです。
やり方としては2つありますので、それぞれの方法を共有します。

※今回はaxiosを使い、APIによりvalueという項目名でPOSTするものとします。

方法1 dataで定義する変数を配列で初期化してv-modelに設定

大体の場合はこのパターンでうまくいきます。

チェックボックスの例)

※中身は要点だけおさえて色々要約して書いています。
testCheckboxValuesの中身はチェックボックスの候補が入った配列です。

<ul>
  <li v-for="testCheckbox in testCheckboxValues">
    <label>
      <!-- v-modelに設定するだけ -->
      <input v-model="checkboxList" type="checkbox" :value="testCheckbox.value"/>{{ testCheckbox.name }}
    </label>
  </li>
</ul>
export default {
  name: ’test'
  data () {
    return {
      checkboxList: [] // 配列で初期化
    }
  },
  methods: {
    postMethod () {
      let params = new FormData()
      // valueという項目名でPOST
      // 配列をそのまま入れるだけ
      params.append('value', this.checkboxList)
      this.axios.post('/api/test/post', params, {
        ・・・・
      })
      .then(res => {
        ・・・・
      })
    }
  }
}

上記のやり方が一番ベーシックですね。
POSTしたい変数を配列で定義し、v-modelに設定するだけで本当に配列としてPOSTできるのです。
画面を開いた時、すなわちGETのタイミングでも、testCheckboxValuesの各valueの中にcheckboxListの値と同じものがあれば、勝手に:checkedが付いてくれるのです。

複数のテキストフォームがある時の例)

※下記はなんらかの方法でtextListの要素数を増やしたり減らしたりできるものとします。

<ul>
  <li v-for="index in textList.length">
    <!-- v-modelに設定するだけ -->
    <input v-model="textList[index - 1]" type="text"/>
  </li>
</ul>
export default {
  name: ’test'
  data () {
    return {
      textList: [] // 配列で初期化
    }
  },
  methods: {
    postMethod () {
      let params = new FormData()
      // valueという項目名でPOST
      // 配列をそのまま入れるだけ
      params.append('value', this.textList)
      this.axios.post('/api/test/post', params, {
        ・・・・
      })
      .then(res => {
        ・・・・
      })
    }
  }
}

上記もただただdataで定義した配列をそのままPOSTしているだけですが、これで配列のPOSTになるのです。
注意点としてはv-modelの指定方法です。
例えば以下のようにしてしまうと、

<ul>
  <li v-for="text in textList">
    <input v-model="text" type="text"/>
  </li>
</ul>

こんなエラーが出てしまいます。

You are binding v-model directly to a v-for iteration alias. This will not be able to modify the v-for source array because writing to the alias is like modifying a function local variable. Consider using an array of objects and use v-model on an object property instead.

よってテキストの配列の場合は、要素を直接v-modelに入れないように注意しましょう。



方法2 POSTする前に配列にまとめてしまう方法

あまりないパターンですが、dataで定義した配列をそのままPOSTできない場面が来た場合は以下の方法もあります。

チェックボックスの例)

<ul>
  <li v-for="testCheckbox in testCheckboxValues">
    <label>
      <!-- v-modelに設定するだけ -->
      <input v-model="checkboxList" type="checkbox" :value="testCheckbox.value"/>{{ testCheckbox.name }}
    </label>
  </li>
</ul>
export default {
  name: ’test'
  data () {
    return {
      checkboxList: [] // 配列で初期化
    }
  },
  methods: {
    postMethod () {
      let params = new FormData()

      // ループで配列に格納
      if (this.checkboxList.length > 0) {
        this.checkboxList.forEach((check, index) => {
          param.append('value[' + index + ']', check)
        })
      } else {
        param.append('value', [])
      }

      // valueという項目名でPOST
      this.axios.post('/api/test/post', params, {
        ・・・・
      })
      .then(res => {
        ・・・・
      })
    }
  }
}

結局POSTする値は方法1の時と同様になりますが、上記のようにループを使って配列に格納することも可能です。
チェックがない場合(this.checkboxList.length === 0の場合)は空の配列を格納することを忘れないでください。

複数のテキストフォームがある時の例)

<ul>
  <li v-for="index in textList.length">
    <!-- v-modelに設定するだけ -->
    <input v-model="textList[index - 1]" type="text"/>
  </li>
</ul>
export default {
  name: ’test'
  data () {
    return {
      textList: [] // 配列で初期化
    }
  },
  methods: {
    postMethod () {
      let params = new FormData()

      // ループで配列に格納
      if (this.textList.length > 0) {
        this.textList.forEach((text, index) => {
          param.append('value[' + index + ']', text)
        })
      } else {
        param.append('value', [])
      }

      // valueという項目名でPOST
      this.axios.post('/api/test/post', params, {
        ・・・・
      })
      .then(res => {
        ・・・・
      })
    }
  }
}

チェックボックスの時とほとんど同じですね。

まとめ

いかがでしょうか。
少なくともjQueryなどを使うよりはVue.jsの方が配列の扱いは簡単ですよね。


基礎から学ぶ Vue.js

基礎から学ぶ Vue.js

速習Vue.js 速習シリーズ

速習Vue.js 速習シリーズ

Vue.jsとFirebaseで作るミニWebサービス (技術書典シリーズ(NextPublishing))

Vue.jsとFirebaseで作るミニWebサービス (技術書典シリーズ(NextPublishing))

Vue.js入門 基礎から実践アプリケーション開発まで

Vue.js入門 基礎から実践アプリケーション開発まで

  • 作者: 川口和也,喜多啓介,野田陽平,手島拓也,片山真也
  • 出版社/メーカー: 技術評論社
  • 発売日: 2018/09/22
  • メディア: 単行本(ソフトカバー)
  • この商品を含むブログを見る