AngularJS と Knockout.js を比較して、個人的には Knockout.js のような ViewModel を採用しているものの方が分りやすい(あと Rails に薄く被せる時とか)と思い、同じように ViewModel を採用している Vue.js を試してみました。
Vue.js の公式ベージ ⇒ http://vuejs.org/
ただ Knockout.js と違いモダンブラウザでないと使えないようです。ただ次期の AngularJS もレガシーブラウザを捨てるようですし、それはいいかな。
今回 Vue.js を試すにあたり、ライブラリを CDN から読みこんでもよかったのですが、ある程度ちゃんとやるために手元に環境を構築しました。
環境構築
Yeoman 公式の webapp ジェネレータを元に、Bower で Vue.js をインストールしました。スクリプトは CoffeeScript で書くのが個人的には楽なので、それも導入します。
webapp
ジェネレータを利用すると Grunt/Bower まわりの環境が一発で揃うので楽です。
ただ、商用向けなど本格的に使うなら、ある程度は知識が必要となり、またやりにくい部分も出てくるとは思います。
前提
-
手元の OS:
Mac OS X 10.9.5 (Mavericks)
-
Yeoman、Grunt、Bower を使います。もしまだインストールしていない場合、こちらの投稿を参考にインストールしてください。
-
webapp ジェネレータをインストールしていない場合は、次のようにインストール。
$ npm install -g generator-webapp
手順
-
ジェネレータを起動。この際、
--coffee
をつけます。$ yo webapp --coffee
-
(少しはデザインが欲しいので)Bootstrap だけ選択します。
-
次のようにファイルが展開されます。
-
Bower で Vue.js と、一応 JQuery もインストールします。
$ bower install vue --save $ bower install jquery --save
-
結果の
bower.json
は次のとおり。bower.json{ "name": "vue", "private": true, "dependencies": { "bootstrap": "~3.2.0", "vue": "~0.10.6", "jquery": "~2.1.1" } }
-
-
次のコマンドを打つと、
index.html
が自動で編集され、Bower でインストールしたライブラリを読む込むようになります。$ grunt wiredep
前は
$grunt bowerInstall
だったのに、変わったのかな.. ジェネレータのバージョンによって変わるかもなので、正確なコマンドはGruntfile.js
を見て調べてください。-
結果の
index.html
は次のとおり。app/index.html<!-- build:js(.) scripts/vendor.js --> <!-- bower:js --> <script src="bower_components/jquery/dist/jquery.js"></script> <script src="bower_components/vue/dist/vue.js"></script> <!-- endbower --> <!-- endbuild -->
-
-
いったん動作確認してみます。
$ grunt serve
もしリリース用にビルドする場合は、$ grunt build
とします。すると dist
フォルダ下に、minify や Cofffee 等のコンパイルされたファイルが展開されます。
この手順で作った環境のソースコードは、GitHub にも置きました。
⇒ https://github.com/hkusu/Vue.js_demo
Vue.js を試してみる
ViewModel を書く
軽く公式ページを確認した感じだと、var hoge = new Vue()
で VewModel を定義し、引数にはオブジェクト {..} を渡すようです。
オブジェクトの el
プロパティには、バインド対象とする View 上の div エリアの id を指定し、利用するデータは data
プロパティ、メソッドは methods
プロパティで定義します。
メソッドの中でデータを利用する場合は、this.hoge
(Coffeeの場合は @hoge)のように参照します。
$ ->
demo = new Vue(
el: "#demo"
data:
firstName: "太郎"
lastName: "山田"
count: 0
#message: "" ← 初期値を設定しないでいいなら省ける
methods:
execute: ->
@message = "実行しました"
return
)
return
この例だと、demo = new Vue()
のように ViewModel インスタンスへの参照を変数にいれたけど、何かに使えるのだろうか?(コンポーネントとして再利用できる?)
View を書く
単純にデータを扱うなら {{..}}
の中に変数を書けばいいです。inputフォームの内容とデータを紐づけるなら v-model
ディレクティブで、イベントは v-on
で取得できます。
ViewModel に定義したメソッドは v-on="click: hoge_method"
のようにして呼び出せます。
<div id="demo">
<h4><font color="orange">データバインドの例</font></h4>
<p>
{{lastName}} {{firstName}}
</p>
<p>
<input v-model="lastName"/> <input v-model="firstName"/>
</p>
<hr>
<h4><font color="orange">クリックイベントの例</font></h4>
<p>
{{count}}
</p>
<p>
<button class="btn btn-primary" v-on="click: count++">カウント</button>
</p>
<hr>
<h4><font color="orange">メソッド実行の例</font></h4>
<p>
{{message}}
</p>
<p>
<button class="btn btn-primary" v-on="click: execute">実行</button>
</p>
</div>
動作確認
こんな感じです。
こちら(GitHub Pages)にデモを置きました。※IE8とかだと動きません。
⇒ http://hkusu.github.io/Vue.js_demo/dist/
感想
とても良い印象です。いまのところ悪いところは無いです。とくに気に入ったのは、
- View で
{{hoge}}
のように書けば、これだけで(ViewModel 側で変数を定義しなくても)Vue.js の 監視対象に追加されるので楽ちん!- デザイナーさんも扱い易いのではないでしょうか。
- Knockout.js のように View に
"data-bind" => "text: hoge"
というように長々と書かなくていいので、View の見た目がごちゃごちゃしない。 - ViewMode 側で div エリアを指定してバインドできる。View 側は特別なことをしなくてよい。
- AngularJS のように
ng-controller=
とかで View を汚さなくてよい。
- AngularJS のように
- ViewModel の構造が分りやすい。
- データは
data
プロパティ、メソッドはmethods
プロパティに書くように縛られているので、一目で何をやっているかが分る。
- データは
ひとことで言うと「分りやすい」です。もし大規模でつかうなら、他のフレームワークと組みあわせればいいのかな?
AngularJS はフルスタックであったり DI ベースであったりと、単純には比較できない(用途や目的が違う)のですが、少なくとも Knockout.js よりはいい感じがします。
次期バージョンの開発も進んでいるようですし(個人的には URLのルーティング機能は欲しい)、期待したいと思います。