
LaravelMixでやるVue.js。今日はフォームに入力した値をVue.jsに覚えさせるところまでやっていこうと思います。今まで、環境構築、ループ、イベント定義について書きました。気になる人は、過去記事見ていただくと分かりやすいと思われます。
Vue.jsのリアクティブ機能とは
Vue.jsのリアクティブ機能とは、Vue.jsのオブジェクトに変更があった場合Viewにデータを提供するといったようなイメージだと認識しています。というわけで、準備していきましょう。
<html> <head> </head> <body> <div id="test"> <table> <tr> <th>駅</th> <th>次の駅</th> <th>前の駅</th> </tr> <tr v-for="(stations,i) in station"> <td><input name="sakuradouri" class="form-control" :value="stations.sakuradouri" @change="changeData" type="text" /></td> <td><input name="next" class="form-control" :value="stations.next" /></td> <td><input name="before" class="form-control" :value="stations.before" /></td> </tr> </table> </div> </body> <script src="{{asset('js/vuetest.js')}}"></script> </html>
前回は:valueのとこv-bind:valueと書きましたが、v-bindを省略することが可能です。 v-bindを省略する書き方でもOKです。
import Vue from 'vue' const exp = new Vue({ el: '#test', data: { densha: '名古屋市営地下鉄桜通線', station: [ { sakuradouri: '名古屋', next: '中村区役所', before: '国際センター', }, { sakuradouri:'国際センター', next:'名古屋', before: '丸の内' }, { sakuradouri: '丸の内', next: '国際センター', before: '久屋大通' }, { sakuradouri: '久屋大通', next: '丸の内', before: '高岳', }, { sakuradouri:'高岳', next: '久屋大通', before: '車道' }, { sakuradouri:'車道', next: '高岳', before: '今池', }, { sakuradouri:'今池', next: '車道', before: '吹上' }, { sakuradouri:'吹上', next:'今池', before: '御器所' }, { sakuradouri:'御器所', next:'吹上', before: '桜山', }, { sakuradouri:'桜山', next:'御器所', before: '瑞穂区役所' }, ], }, methods: { changeData: function(e) { alert(e.target.value); }, } });
こんな感じで。前回は、文字入力した際に、alertが出て終わっていたと思います。この状態だと、イベントは設定できるものの、Vue.jsのオブジェクト自体に変更を加えてないのでリアクティブできていないと考えます。なので、今日はVue.jsのdataプロパティを修正する方法を書いて行きます。ちなみに前回はVue.jsのイベント設定に書きました。不安な方は、前回記事を面倒ですが読んでくださると分かりやすいです。
Vue.jsオブジェクトへのデータ保存
Vue.jsオブジェクトへデータを保存するというのは、Vue.jsオブジェクトの中のdataプロパティの特定キーへのデータの保存を抽象化してこう言ってます。これを、イベント発生時に保存してみましょう。これをやる為に、イベント発生時にキーを取れるようにViewを修正していきます。
データ保存時のキー取得
Vue.jsでデータを保存する際にキーを取得する為に、DOMにキー情報を持たせます。行情報をv-bindで記憶させていますが、もっといいやり方はあると思われます。良いやり方あれば教えてください。というわけでコードです。
<html> <head> </head> <body> <div id="test"> <table> <tr> <th>駅</th> <th>次の駅</th> <th>前の駅</th> </tr> <tr v-for="(stations,i) in station"> <td><input name="sakuradouri" class="form-control" :value="stations.sakuradouri" @change="changeData" type="text" :data-row="i" /></td> <td><input name="next" class="form-control" :value="stations.next" @change="changeData" :data-row="i" /></td> <td><input name="before" class="form-control" :value="stations.before" @change="changeData" :data-row="i" /></td> </tr> </table> </div> </body> <script src="{{asset('js/vuetest.js')}}"></script> </html>
trに行情報持たせても良いのですが、親ノードから行情報取るしか方法思いつかないので、リアクティブしてるDOMにそのまま書いてます。親ノードから行情報を取る場合、HTMLの構造が変わった場合に不具合が起きてしまうので、あんまり好ましくないです。絶対にHTMLの構造が変わらないとか、作業した人がずっと保守するシステムであれば親ノードから行情報取っても良いと思います。
既にある値を変更して保存
キーを設定したので、対象の行の値を変更していきます。実戦で使う場合は、各Input要素に対してイベントを紐づけた方が良いと思いますが、今回は、一個のメソッドでやります。
import Vue from 'vue' const exp = new Vue({ el: '#test', data: { densha: '名古屋市営地下鉄桜通線', station: [ { sakuradouri: '名古屋', next: '中村区役所', before: '国際センター', }, { sakuradouri:'国際センター', next:'名古屋', before: '丸の内' }, { sakuradouri: '丸の内', next: '国際センター', before: '久屋大通' }, { sakuradouri: '久屋大通', next: '丸の内', before: '高岳', }, { sakuradouri:'高岳', next: '久屋大通', before: '車道' }, { sakuradouri:'車道', next: '高岳', before: '今池', }, { sakuradouri:'今池', next: '車道', before: '吹上' }, { sakuradouri:'吹上', next:'今池', before: '御器所' }, { sakuradouri:'御器所', next:'吹上', before: '桜山', }, { sakuradouri:'桜山', next:'御器所', before: '瑞穂区役所' }, ], }, methods: { changeData: function(e) { let name = e.target.getAttribute('name'); let row = e.target.getAttribute('data-row'); this.$set(this.station[row],name,e.target.value); alert(name+'の'+row+'番は'+e.target.value+'に変更されました。'); console.log(this.station[row].next); }, } });
これで、0番目の行を「中村区役所」を「中村区役所駅」に変更すると、アラートが表示されて、変更されたとメッセージがでます。コンソールで、メッセージを見ても、該当行が変更されていることが確認できます。

Vue.jsでのデータの受け渡しは以上になります。今までの記事と合わせれば、なんとなくVue.jsを扱えるのではないでしょうか。Vue.jsの自分の理解棚卸作業は、まだ…続きます!