前回の続きになります。
Vue.js入門その1〜基本文法〜
今回は下記の公式ドキュメントのメモになります。
なお、今回もJSFiddleを使用していきたいと思います。
Vue.jsではルートVueインスタンスを作成することで起動されます。
前回何度も記述したやつです。
var vm = new Vue({ // オプション })
ちなみに、vm
はViewModelの意味であり、MVVMパターンの影響を受けているとのことです。
私は前回、Vueインスタンスをapp
という変数に保存しておりましたが、慣例的には誤りだったということになります。
(申し訳ありません!)
Vueインスタンスは、自身のdata
の値を持ちます。data
が変更されると、Vueインスタンスのプロパティも変化し、その逆も然りです。
試しに、下記のコードを書き、インスタンスを生成します。
var data = { a: 1 } var vm = new Vue({ data: data }) window.vm = vm; window.data = data;
コンソールで操作したいので、インスタンスを渡しています。
下記のように試すと、vm
のプロパティとdata
が一緒に変動していることが分かります。
インスタンスプロパティとして宣言する場合は、vm.$data
とも書けます。
DOMのid
を取得する場合は、vm.$el
です。
これとは別に、インスタンスメソッドもあります。$watch
で、対象のプロパティが変化したときに呼ばれます。
コールバックで古い値と新しい値を引数で受け取ることができます。
$watch (Vue.jsリファレンス)
<div id="example"> {{ a }} </div>
var data = { a: 1 } var vm = new Vue({ el: '#example', data: data }) vm.$watch('a', function (newVal, oldVal) { console.log(oldVal + 'から' + newVal + 'に変わりました!'); }) window.vm = vm; window.data = data;
これで、a
プロパティを監視してくれますので、コンソールにて値を変更すれば、$watch
で定義した処理が実行されます。
Vueインスタンスが作成されたり、更新されたりするタイミングでフックされる処理を定義できます。
例として、インスタンスが生成されるときにフックされるcreatedで書きます。
var vm = new Vue({ data: { a: 1 }, created: function() { console.log('created!!'); } })
これで、インスタンス生成時(JSFiddle実行時)にコンソールに「created!!」という文字が表示されます。
ライフサイクルフックは他にもありますが、試しにdestroyedも使用してみます。
var vm = new Vue({ data: { a: 1 }, created: function() { console.log('created!!'); }, destroyed: function() { console.log('destroyed!!'); } }) window.vm = vm;
インスタンスが生成された場合は「created!!」、削除された場合は「destroyed!!」と出力されます。
削除するときは、コンソールで下記を入力すればOKです。
> vm.$destroy()
$destroyはインスタンスを強制的に破棄するインスタンスメソッドです。
例えば、下記のようなコードがあります。
<div id="app"> {{ msg | defaultMsg }} </div>
var vm = new Vue({ el: '#app', data: { msg: 'Hello from JSFiddle!!' } })
このとき、msg
の値を操作し空文字を渡せば空欄になります。
ただ、空文字の場合はデフォルトの文字をセットしたいこともあります。
そのようなときに使うのがフィルタです。
フィルタの使用を宣言する場合は、|
を使用します。
まず、HTML側を下記のように変更します。
<div id="app"> {{ msg | defaultMsg }} </div>
これで、msg
をdefaultMsg
でフィルタする宣言になります。defaultMsg
はVueインスタンスの中で宣言します。
var vm = new Vue({ el: '#app', data: { msg: 'Hello from JSFiddle!!' }, // フィルタ filters: { defaultMsg: function (value) { if (!value) { return 'Hello from defaultMsg'; } return value; } } }) window.vm = vm;
第一引数にはmsg
が入ってきます。
これで、コンソールを使って空文字を渡すと、「Hello from defaultMsg」に変更されます。
このような式もVue.jsでは評価できるようですが、非常に読みにくいため、算出プロパティと呼ばれるものを使用することが推奨されています。
<div id="example"> // messageを逆順に表示する {{ message.split('').reverse().join('') }} </div>
<div id="example"> <p>元のmessage: "{{ message }}"</p> <p>逆順にしたmessage: "{{ reversedMessage }}"</p> </div>
var vm = new Vue({ el: '#example', data: { message: 'Hello' }, computed: { reversedMessage: function () { return this.message.split('').reverse().join('') } } })
新しく出てきたのはcomputedになります。computed
を宣言することであたかもgetterやsetter関数として使用することができます。
今回はreversedMessage
で逆順並び替えを実施しています。
ここで私も思いましたが、これはメソッドと何が違うんだろうと感じるかと思います。
公式リファレンスによると、下記になります。
算出プロパティの代わりに、同じような関数をメソッドとして定義することも可能です。最終的には、2つのアプローチは完全に同じ結果になります。しかしながら、算出プロパティは依存関係にもとづきキャッシュされるという違いがあります。算出プロパティは、それが依存するものが更新されたときにだけ再評価されます。これはつまり、messageが変わらない限りは、reversedMessageに何度アクセスしても、関数を再び実行することなく以前計算された結果を即時に返すということです。
要は依存するプロパティが変更されたときだけ実行されるよ、ということかと思っています。
ただ、再描画したタイミングで必ず実行されるわけではなさそうなので、慣れないうちはメソッドの方が良いのかもしれません(パフォーマンスを考えなければ)。
インスタンス上のデータの変更を監視し、反応させることができる監視プロパティというものもあります。
例えばwatchになります。
以下の例題は、苗字と名前を監視し、フルネームを返しています。
<div id="demo">{{ fullName }}</div>
var vm = new Vue({ el: '#demo', data: { firstName: 'Foo', lastName: 'Bar', fullName: 'Foo Bar' }, watch: { firstName: function (val) { this.fullName = val + ' ' + this.lastName }, lastName: function (val) { this.fullName = this.firstName + ' ' + val } } }) window.vm = vm;
ここで、コンソールで下記のようにfirstName
とlastName
を変更すると、「hoge fuga」と表示されます。
> vm.firstName = 'hoge'; < "hoge" > vm.lastName = 'fuga' < "fuga"
ただ、上記のコードは算出プロパティを使用して書き換えることもできます。
こちらの方がコード量は短くなりますね。
var vm = new Vue({ el: '#demo', data: { firstName: 'Foo', lastName: 'Bar' }, computed: { fullName: function () { return this.firstName + ' ' + this.lastName } } }) window.vm = vm;
算出プロパティでsetter関数を定義することもできます。
先ほどの例の逆で、フルネームの値を変更すると、苗字と名前も変更されるようにします。
<div id="demo"> <p>フルネーム:{{ fullName }}</p> <p>ファーストネーム:{{ firstName }}</p> <p>ラストネーム:{{ lastName }}</p> </div>
var vm = new Vue({ el: '#demo', data: { firstName: 'Foo', lastName: 'Bar' }, computed: { fullName: { get: function () { return this.firstName + ' ' + this.lastName }, set: function (newValue) { var names = newValue.split(' ') this.firstName = names[0] this.lastName = names[names.length - 1] } } } }) window.vm = vm;
先ほどまでのgetterのみであれば、プロパティの後にそのまま関数で良かったのですが、setterも含める場合は、get
とset
で分ける必要があります。
このあたりはcomputedにも記載があります。
これで、コンソールでfullName
を変更すれば名前と苗字も一緒に変わります。
今回はVueインスタンスのプロパティやメソッドの紹介でした。
まだ漠然としていますね。。。
次回は試しに、ここまでの内容で何か作ってみたいと思います!