Vue.js で表示したデータの更新とイベント処理

Vue.js を使って表示したデータをイベントを使って更新します。

自分で要素を更新しなくても良い

データ(変数)が更新されたら自動的に DOM も更新され、逆に項目選択やフォーム入力値などで値が更新されたらデータも更新されるというように今まで自分で書いていた処理を Vue がしてくれます。

ちなみに私が JavaScript のフレームワークをどれかやってみたいと思った一番の理由がこの機能が便利そうだったからです。今までは内容が変わったら更新が必要なところで自分で都度トリガーしていたわけですが、フレームワークで監視してくれると必要な所で更新がされていなかった!とか逆に無駄な処理をしていた!みたいな基本的なバグも起きにくくなりそうです。

イベント処理を登録する

「ボタンをクリックした時」など イベント を利用するには v-on ディレクティブを使います。v-on@で省略が可能です。jQuery の on と似てますね!

<button v-on:click="処理内容やメソッド名">click!</button>

修飾子を使えば JavaScript でよく使う event.preventDefault() などの指定もできます。

単純なテキストを更新する

普通のテキストを更新してみましょう。以下はボタンをクリックすると methods に登録してある test1 を実行します。処理はメッセージの内容を押す度にデータにある count の数を増やします。表示している場所も変えないといけないから要素を探して…みたいな事はしていません(๑'ᴗ'๑)

<p>あなたは{{ count }}回クリックしたよ</p>
<button @click="test1">click!</button>

jQuery のようにテキストを要素で囲む必要もありません。

var vm = new Vue({
el: '#app',
data: {
count: 0
},
methods: {
test1: function() {
this.count++
}
}
})

値には式が使えるので使いまわす予定のない短いコードならメソッドを用意しないで直接式を書くことも出来ます。

<button @click="count++">click!</button>

リストのデータを更新する

配列を更新

リストの一部のインデックス 0 の「りんご」のデータを更新してみます。

<ul>
<li v-for="val in test2list">{{ val }}</li>
</ul>
<button @click="test2">click!</button>
var vm = new Vue({
el: '#app',
data: {
test2list: ['りんご', 'ばなな', 'いちご']
},
methods: {
test2: function() {
this.test2list[0] = 'もぐもぐ'
}
}
})

何も考えずにこう書いてみたけどこれは出来ないみたい。 参考

参考 URL を読むと、JavaScript の制限で配列は直接変更出来ないから内容が変わった事を Vue が察知できるように $set メソッドを使ってねーという事です。多分セッターが使用できるのは対象がオブジェクトの場合だけだからかも。

vm.$set(object, key, value)

上のデータに置き換えるとこんな感じですね。メソッドの内容を書き直します。

this.$set(this.test2list, 0, 'もぐもぐ')

今度はちゃんと更新されました。

オブジェクトを更新

オブジェクトは特に滞りなく変更できました。

<ul>
<li v-for="(val, key) in test4list">(Key:{{ key }}) {{ val }}</li>
</ul>
<button @click="test4">click!</button>
var vm = new Vue({
el: '#app',
data: {
test4list: {
'a': 'ハンバーグ',
'b': '焼肉',
'c': 'パスタ'
}
},
methods: {
test4: function() {
this.test4list.a = 'もぐもぐ'
}
}
})

オブジェクトのリストを更新

また配列なのですがとりあえず $set を使わずに試してみます。

<ul>
<li v-for="(val, no) in test5list" v-bind:key="val.name">
(No:{{ no }}) {{ val.name }} {{ val.price }}円 {{ val.sale }}
</li>
</ul>
<button @click="test5(980, $event)">click!</button>

引数を持たせてインラインで実行する事もできます。この場合 $event で元のイベントオブジェクトを渡せます。

var vm = new Vue({
el: '#app',
data: {
test5list: [{
'name': 'とまと',
'price': '100'
}, {
'name': 'れたす',
'price': '200'
}, {
'name': 'きゅうり',
'price': '300'
}]
},
methods: {
test5: function(price) {
this.test5list[0].price = price
this.test5list[0].sale = 'おすすめ'
}
}
})

出来ました。配列の値を直接弄るわけでなければ大丈夫みたいです。中のオブジェクトのセッターが働いているのでしょうか。手元でセッター付きオブジェクトのネストの実験をしてみたのですがセッター&ゲッターについてもちょっと勉強できました。

データを更新する時のハマりポイント

オブジェクトにネストされていた場合でも、インデックス数値を使って配列を更新する場合は $set を使わないと反応してくれません!どうしてもな場合以外は最後みたいにオブジェクトのリストにしてしまうのが楽かもしれませんね。

まとめ

データを結びつけて更新させるのは jQuery でごにょごにょ書くよりとても楽ですが、それでもデータを複雑に使用するようになるにつれてデータの整合性を保つのが大変になってくる…とよく聞きます。そこまで大きなアプリを作ったことがないので漠然としたイメージしか出来ませんが。そこで登場するのが Vuex らしいのですけど勉強するのはまだまだ先になりそうかな!

とりあえず今回は v-on でのイベント登録の仕方とデータ更新の基本を覚えましたよ(•ө•)ノ 次回は条件を付けて何か操作したいと思います。たぶん。