値を配列で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の方が配列の扱いは簡単ですよね。
- 作者:mio
- 発売日: 2018/05/29
- メディア: 単行本(ソフトカバー)
- 作者:山田祥寛
- 発売日: 2018/03/28
- メディア: Kindle版
Hello!! Vue.js 最新プログレッシブフレームワーク入門 Hello!!Vue&Nuxtシリーズ (技術の泉シリーズ(NextPublishing))
- 作者:那須 理也
- 発売日: 2018/04/13
- メディア: Kindle版