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のルーティング機能は欲しい)、期待したいと思います。




