はじめに
AngularJS(1.x)との違い
設計の違い
AngularJSはMVC(厳密にはMVW?)、対してVue.jsはMVVM、ViewとControllerの間にView Model(VM)を挟み、AngularJSのようにControllerと画面(View)を対応させるのではなく、VMと画面(厳密には画面のUIコンテナ(コンポーネント))を対応させています。
Vue.js(というかMVVM)ではControllerは隠蔽されています。
AngularJSはController駆動(ドリブン)、Vue.jsはModel駆動といえると思います。
AngularJSは大規模アプリを想定しているため、中小規模アプリでは高コストすぎる機能も本体に含んでいますが、Vue.jsは必要な機能のみを組合せて利用することを前提としているのか、いらない機能は本体に含まず、本体はViewまわりのみの最少構成を維持する方向となっています。
(上記はMVC・MVVMの解説ではありません、Vue.jsとAngularJSのしくみの違いについて書いているのみです。MVC・MVVMについて詳しく知りたければ、Wikipedia等をあたるのが正解です。)
MVVM
DI(Dependency Injection)とバインディング
AngularJSではControllerとViewのバインディングを行っていますが、Vue.jsはView Model(VM)とViewでバインディングを行っています。
AngularJSではデータと振る舞いControllerとModelに分離されているため、画面のUIコンテナ(コンポーネント)のルート要素にControllerを紐付けた上でController経由でModelを画面と紐付ける形になりますが、Vue.jsではVMにデータと振る舞いを一元化しているので、画面のUIコンテナ(コンポーネント)にVMを紐付るだけで済みます。
ViewとVMのバインディングはVue.jsにより管理されるため、VMを隠蔽されたControllerとは切り離して考えることができます。
Vue.jsではフォームの入力系要素の値はVMとViewの間で適切に紐付けを行っていると、VM⇔View間で自動的に同期されます。
AngularJSではデータと振る舞いが別々に存在し、それらとViewを繋ぐ糊が必要であるため、DI(Dependency Injection)機能を標準搭載していますが、Vue.jsではViewとVMの間でデータと振る舞いの紐付けを完結できるので、DI機能は標準搭載されていません。
Modelの扱い
AngularJSではModelは基本、振る舞いを持たないデータの入れものにすぎませんが、Vue.jsのView Modelはデータと振る舞いを持っています。
Web Components
PolymerとWebComponents
http://steps.dodgson.org/b/2013/05/19/polymer-and-web-components/
AngularJS(1.x)はWeb Components仕様及びそのPolyfill実装であるPolymerを考慮していないため、組合せての利用では問題があることが指摘されていて、2.0でWeb Components仕様 及びPolymer(のPlatform.js?)への対応が予定されていました。
Vue.jsでは0.11.xでWeb Components最新?仕様との同調?が予定されていました。
コンポーネント指向
Vue.jsはAngularJS(1.x)とは違い、既存のor新規作成したUIコンポーネントを組合せてページを構成することを前提にしています。
オブジェクト指向
AngularJS(1.x)はClassベースではありませんが、Vue.jsはオブジェクト指向となっています。
AngularJS(1.x)についてはAngular Classy を被せることによりClassベースでの開発(Controllerまわりのみ)が行えるようになります。
Angular Classy
http://davej.github.io/angular-classy/
Angular(JS)は2.0以降でClass(ES6ではなくTypeScript)ベースとなっています。
ブラウザー・サポート
AngularJS(1.x)はレガシー・ブラウザをサポートしています。
Angular(JS)は2.0以降でレガシー・ブラウザを切り捨てていますが、高速な動作が実現されているかは要検証です。
AngularJS(1.x)はレガシー・ブラウザーに特化した設計となっていて、モダン・ブラウザ向けのチューニングを行う(モダン・ブラウザを用いて高速化できる処理を切出し、レガシーブラウザとモダン・ブラウザで処理を切換えられるようにする?)ことが難しい模様。
構文の違い
ディレクティブ (directive)
AngularJSとはディレクティブの定義が異なり、Vue.jsのディレクティブは要素に付加できる独自属性であり、この機能により、VMとViewの結びつけを行うとともに、Vue.js組込みor独自定義したディレクティブを要素に付加することにより、要素を操作することができます。
AngularJS(1.x)ではHTML仕様による要素の属性毎に対応した独自属性を用意していますが、Vue.jsは要素の属性をVMのデータと対応させるためのディレクティブv-bind(旧v-attr)のみが用意されています、v-bindで要素の属性(複数可)とVMのデータとの対応を記述するようになっています。
イベント操作も同様に、AngularJS(1.x)ではHTML仕様のイベント毎に対応した独自属性を用意していますが、Vue.jsは要素のイベント(操作)をVMのふるまい(メソッド)と対応させるためのディレクティブv-onのみが用意されています、v-onで要素のイベント(複数可)とVMのメソッドとの対応を記述するようになっています。
独自のディレクティブ(カスタム・ディレクティブ)を定義し利用することも可能です。
コンポーネント(component)
Vue.jsのComponentはAngularJSのディレクティブに相当する機能です。
Angular2.0開発の迷走
2.0発表時の設計資料から察せられる通り、Angular(JS)は2.0でかなり手が入り、1.xとはだいぶ変わること、が確定していました。
既に大きなフルスタックフレームワークであり、2.0の開発がどうなるかは未知数、革新ではなく下位互換に重点を置きすぎる、と開発が停滞する可能性もありました...。
Angular2.0は、ES6+ES7の一部+α という、当時まだフル実装の存在していないJS仕様をターゲットに開発が行なわれていたため、Angular(JS)の開発者にとっては挑戦として面白かったのかもしれませんが、リリースまでには長い時間が必要となる懸念がありました。
ES6の実行環境の実装によっては、ある程度、実装が進んだ段階で 大きな手戻りが必要になるリスクも懸念されていました。
ES6→ES5の Traceur Compiler はあったものの、ES6の実行環境が存在しなかったこともあり、実用レベルには達しておらず、ES6 をフル?実装した主要ブラウザが出揃うまで、正式版がリリースされない可能性を高めていました。
ES6、仕様自体はfreezeされていたものの、仕様の発行がレビュー及び実装からのフィードバックを反映するため2015/06 に延期されたりもしました。
Object.oberve等、ES6では入らずES7以降へ持ち越しとなっていた機能のいくつかが、前倒しになる可能性が限りなく低いです がありはしました。その後、Object.oberve は仕様から取り下げられています。
フルスタックでありながら、ほんの数人のエンジニア
だけで開発されていることも開発の長期化を予感
させました。
2.0では、Web Comopnents仕様対応かつ自律した
UIコンポーネントを作成できることがGoogleブランドで あり続けるためには外せないであろうことも、開発期間の長期化を予感させました。
発表時点でリリース時期未定 となっていたことからも、1.xとは大幅に変わるのは ほぼ確実でした が、Angular(JS)2.0を1.xとそれほど大きく変えず、早期リリースの実現を目指すことも考えられました。
その場合、Angular(JS)2.0は淘汰され消えていたでしょう、変化を許容できないFWは生き残れません。
2015/03に Angular2.0の開発において大幅?な変更がありました。
当初、Traceur Compiler ベースでの ES6→ES5 変換を利用してのES6ベースでの開発が予定されていましたが、Traceurが期待するほどの変換能力を実現できていないことから、AtScriptという名前でES5ベースにES6の一部機能をツッコんだAltJSを開発する方向に方針を変更、更に、独自に開発していては開発に時間が掛かる上に枯れて問題なく利用できるレベルに達するのにも時間を要するためか、AtScriptの開発をMS主体で開発が進められているTypeScriptに合流することが決定されました。
Traceur Compiler(Google) → AtScript(Google) ⇨ TypeScript(MS)...。
Angular2.0開発における一番?の懸念材料であったES5・ES6両対応のための足回りの問題がこれで解消に向かいました。
この開発方針の変更に合わせ、Angular2.0のリリース時期も2015/03時点で来年と発表されました。
他の懸念材料は残っていましたが、GoogleがAngularに投入している人的リソースから考えると、妥当な判断だったのではないかと思います。Angular2.0はそれまで大風呂敷を広げすぎていて、人的リソースから考えると、開発期間が長期化せざるをえない状況にありました。
Angular2.0は、この発表時点で、設計段階か初期プロトタイプ・フェーズにあったようなので、
この発表以降もリリース時期を守るためには予断を許さなかった のではないかと思います。
AngularJS(1.x)のように、マニアックで場当たり的な (そのようにみえる)設計にしてしまうと、もたらされる恩恵に比べて 学習コストが非常に高くつくモノ、となってしまいます。
(以前書いた)上記の懸念もありましたが、2016/09/14、Angular2.0がリリースされました。
2.0での開発の迷走が大きく影響しているのか、Angularは2.0以降、革新的な機能の追加はないようにみえます。
2.0の仕様案?では予定されていた?vDOMの導入は、早期リリース のために?見送られました。
Angularでは、結局、vDOM対応は行われず、代わりに、バージョン9(2020/12リリース)から
Incremental DOMが導入されています。
Incremental DOM は 仮想DOM 同様、変更のみ(DOMに)反映するための技術です。
Angular16(2023/05/03リリース)にてSolid.jsのSignalにインスパイアされた機能 Angular Signalsも導入されています。