MVVM は、Model-View-ViewModel の略称で、フロントエンド開発に基づいたアーキテクチャ パターンであり、View と View Model の間の双方向のデータ バインディングを提供し、View Model の状態変更を可能にします。これは、双方向データ バインディングと呼ばれます。
Vue.js は、View レイヤーに重点を置いた MVVM スタイルの双方向データ バインディングを提供する Javascript ライブラリです。そのコアは MVVM の VM、つまり ViewModel です。 ViewModel は、ビューとモデルを接続して、ビューとデータの一貫性を確保する役割を果たします。この軽量アーキテクチャにより、フロントエンド開発がより効率的かつ便利になります。
なぜMVVMが登場するのですか?
私が MVVM に出会ったのは 2015 年でした。それまで私が MVC に出会ったのは約 5 年前、つまり 2011 年でした。 , 当時私はプログラミング言語を学んだばかりで、Java を学び、Java の古典的な SSH フレームワークを使用して標準の MVC アーキテクチャを構築しました。正直に言うと、私は MVC アーキテクチャを長年使ってきましたが、Vue.js に出会って初めて、使用するレベルでしか理解できませんでした。 MVVM アーキテクチャの考え方を理解して、MVC を振り返ってみると、ふと悟ったような気がしました〜
MVC とは、Model-View-Controller の略で、つまり、標準的な Web アプリケーションです。次の 3 つの部分で構成されます:
View は何らかの方法でデータを変換するために使用されます
Model は実際にはデータです
Controller はユーザーからのリクエストを受信して処理し、Model をユーザーに返します
HTML5 がまだ普及していなかった時代、Web アプリケーションのベスト プラクティスは MVC でした。これは、Web アプリケーションの View 層が比較的単純で、フロントエンドで必要なデータは基本的にバックエンドで処理できるためです。 View 層は主に表示用であり、複雑なビジネスを処理するために View 層が提唱された、いわゆるシン クライアントのアイデアです。
2010 年から 2011 年にかけて、HTML5 の概念が宣伝され、求められました。2012 年に、W3C は HTML5 仕様が正式に完成したと正式に発表しました。私が入社した 2013 年に、HTML5 フレームワークである Sench touch に出会いました。Sench touch は、フロントエンドとバックエンドを完全に分離する HTML5 フレームワークです。独立したプロジェクトとして使用されます。
MVC を使用する場合、なぜフロントエンドを設計する必要があるのですか?
HTML4 と比較した場合、HTML5 の最大のハイライトは、モバイル デバイスにいくつかの非常に便利な機能を提供し、HTML5 でアプリを開発できるようになることです。HTML5 でアプリを開発する最大の利点は、クロスプラットフォーム、迅速な反復と起動、労力の節約です。コストと提出効率を考慮して、多くの企業が従来のアプリを変革し始め、2015 年までに、市場の多くのアプリに多かれ少なかれ H5 ページが埋め込まれました。
H5 を使用してアプリを構築したいので、View レイヤーは単純なデータの表示だけではなく、ユーザーの操作のさまざまなステータスを管理し、モバイル デバイスでのユーザーのさまざまな操作を処理する必要があります。の上。したがって、これらの複雑なロジックを管理し、開発をより効率的にするには、フロントエンドにも MVC に似たフレームワークが必要です。 しかし現時点では、MVC は少し変更されています:
View UI レイアウト、データを表示
Model がデータを管理
Controller がユーザー操作に応答し、Model を View に更新
この MVC アーキテクチャ パターンは、基本的なアプリケーションに適しているようですこれは、ソフトウェア アーキテクチャの階層化された考え方と一致しています。 しかし実際には、H5 の継続的な開発により、人々は H5 を使用して開発されたアプリケーションがネイティブと同等、またはネイティブ アプリのエクスペリエンスに近いものになることを期待しています。そのため、フロントエンド アプリケーションの複雑さは以前のものではなくなりました。この時点で、フロントエンドには 3 つの重要な問題点が明らかになりました:
1. 開発者はコード内で同じ DOM API を多数呼び出すため、処理が煩雑で冗長になり、コードの保守が困難になります。
2. 多数の DOM 操作により、ページのレンダリングのパフォーマンスが低下し、読み込み速度が遅くなり、ユーザー エクスペリエンスに影響します。
3. モデルが頻繁に変更される場合、開発者はビューを積極的に更新する必要があります。ユーザーの操作によってモデルが変更されると、開発者は変更されたデータをモデルに同期する必要もあります。
このような作業は面倒なだけでなく、困難でもあります。複雑で変化するデータのステータスを維持します。
実際、jquery の初期の登場は、フロントエンドが DOM をより簡潔に操作するためのものでしたが、それは最初の問題を解決しただけで、次の 2 つの問題はフロントエンドに常に存在していました。
MVVMの登場により、上記3つの問題は完璧に解決されました。
MVVM は、モデル、ビュー、ビューモデルの 3 つの部分で構成されます。モデル層はデータ モデルを表し、データの変更と操作のビジネス ロジックもモデル ビューで定義できます。データモデルをUI表示に変換し、ViewModelとViewとModelを同期させるオブジェクトです。
MVVM アーキテクチャでは、View と Model の間に直接的な接続はなく、ViewModel を通じて対話するため、View データの変更はモデルとモデル データに同期されます。変更はビューにもすぐに反映されます。
ViewModel は双方向のデータ バインディングを通じて View レイヤーと Model レイヤーを接続し、View と Model の間の同期は人間の介入なしで完全に自動化されるため、開発者はビジネス ロジックに集中するだけでよく、DOM を手動で操作する必要はありません。複雑なデータステータスの同期を意識する必要はありません。MVVM によって完全に管理されます。
Vue.jsの詳細
Vue.jsはMVVMアーキテクチャのベストプラクティスと言え、双方向のデータバインディングを実現するだけでなく、比較的軽量なJSライブラリです。 、API はシンプルで使いやすいです。 Vue の基本知識についてはインターネット上に既製のチュートリアルがあるため、ここでは詳しく説明しません。双方向バインディングに関する Vue.js の実装の詳細をいくつか簡単に見てみましょう:
Vue.js Object.definePropertyのgetterとsetterを使用し、それらを組み合わせてデータバインディングを実装するためにObserverパターンを使用します。プレーンな Javascript オブジェクトをデータ オプションとして Vue インスタンスに渡すと、Vue はそのプロパティを反復処理し、Object.defineProperty を使用してプロパティをゲッター/セッターに変換します。ゲッター/セッターはユーザーには表示されませんが、内部的には Vue が依存関係を追跡し、プロパティがアクセスされ変更されたときに変更を通知することができます。
データオブジェクトのすべてのプロパティを監視できるオブザーバーデータリスナーは、変更がある場合に最新の値を取得し、Object.defineProperty
のゲッターとセッターを使用して内部的に実装されます。コンパイル命令パーサー、その役割は、各要素ノードの命令をスキャンして解析し、命令テンプレートに従ってデータを置き換え、対応する更新関数をバインドすることです
ウォッチャーサブスクライバーは、オブザーバーとコンパイルを接続するブリッジとして、サブスクライブして、属性変更の各通知を受信し、命令によってバインドされた対応するコールバック関数を実行します
Dep メッセージ サブスクライバは、サブスクライバ (ウォッチャー) を収集するための配列を内部的に維持し、データ変更が通知関数をトリガーし、サブスクライバの更新メソッドを呼び出します
new Vue() が実行されると、Vue は初期化フェーズに入ります。一方、Vue はデータ オプションのプロパティを走査し、Object.defineProperty を使用してそれらをゲッター/セッターに変換し、データ変更監視関数を実装します。一方、Vue の命令コンパイラは、要素ノードの命令をスキャンして解析し、ビューを初期化し、ビューを更新するために Watcher にサブスクライブします。このとき、Water は自身をメッセージ サブスクライバ (dep) に追加します。初期化が完了しました。
データが変更されると、オブザーバーの setter メソッドが直ちに Dep.notify() を呼び出します。Dep は、サブスクライバーが通知を受信した後、サブスクライバーの update メソッドを呼び出します。ビューを更新し、対応する更新を行い、データ バインディングを完了します。