データバインディングについてVue.jsと Backbone.stickitを比較する
これは会社でvue.jsを採用を説得するための資料なのでstickitを罵倒する
vue.js http://vuejs.org/
backbone.stickit http://nytimes.github.io/backbone.stickit/
Backbone.stickitとVue.jsの比較
「#menuを押したら右に100px動く」みたいなコードを書いてみるとする。 template関数はJadeテンプレートを展開する関数だと思ってほしい
Backbone.stickit の場合
class MenuView extends Backbone.View initialize: -> @model = new Backbone.Model() @render() render: -> @$el.html template(""" #menu.js-open """) @stickit() bindings: '.js-move': observe: 'positionX' update: ($el, model, val) -> $el.css 'left', val
テストケース
it 'should move to left 100', -> menu = new MenuView menu.move() expect(menu.model.get 'positionX').eq 100
問題
- Backbone.stickitにとっては、DOMが観測主体である
- 'on chagnge' に依存して発火するので、ネストした値は同期できない(Backbone.Modelの問題)
- Viewとテンプレートにまたがってやや複雑な手続きになる
- updateの中でjQueryを記述するのは自由度は高いがメンテナビリティが低い
Vue.jsの場合
Menu = Vue.extend template: template """ #menu(style="left: {{positionX}}px" v-on="click: move") """ data: positionX: 0 methods: move: -> @$data.positonX = 100
テストケース
it 'should move to left 100', -> menu = new Menu menu.move() expect(menu.$data.positionX).eq 100
このとき、Menuのインスタンスはビューモデルだが、Backbone.View相当のものはViewModelの下に完全に従属していると言って良い。
メリット
- 記述ステップが短い(手続き的ではなく宣言的である)
- ViewModel(Vue)がViewを隠ぺいする
- テンプレートで余計な装飾が不要で直感的
Viewが隠蔽されることで、見た目上、ピュアなJavaScriptオブジェクトだけを相手にしてコードが書けるようになる。これによって複雑怪奇なDOMの相手を極力減らすことができる。
経験上、DOMとViewクラスを完全に分離して再利用できたことは一度もない。凝集性の重視して密結合することで見通しをよくするのはアリだと思う。
何が言いたいか
Viewで扱うパラメータをViewModelのパラメータ化して隠蔽したい。get/setがカッコ悪い。バインドされてる値を特殊なものだとして扱いたくない。
Angularと比べた時のメリット
Angular巨大すぎ。学習コスト高すぎ。DSL汚すぎ。(個人の見解です)。 少なくとも途中からの移行は不可能なので考えない。
中の人から翻訳記事書いて欲しいとのこと
@mizchi Someone translate it to English please XD
— Vue.js (@vuejs) 2014, 2月 18
@vuejs My English is not so good but I can try later!
— 高意識エネルギー (@mizchi) 2014, 2月 18