# MVVMとは

MVVMは **モデルからビュー / ビューからモデル** への**データバインディング**(UIへのデータの割り当て/束縛)の為に使われる設計手法です。**データバインディング**(**Data Binding** = 直訳だと束縛)というのは、データとUIを関連付ける仕組みです。MVVMを使わない実装(個別に都度input要素の値を書き換える手法)については、以下で説明していますので、まだの方は見てみてください。

{% content-ref url="../manual/input-form/naformnodtabaindingu" %}
[naformnodtabaindingu](https://docs-f.mix-soft.com/manual/input-form/naformnodtabaindingu)
{% endcontent-ref %}

MVVM自体は特定の言語・実行環境に関連づかない設計手法なので、GUIを実装する場合(デスクトップ・アプリケーション/モバイル/Web)であれば広く使える考え方です。今回はWebなのでWebで説明すると

* モデル(データ) = JavaScriptのオブジェクト(もしくはクラスのインスタンス)
  * 例: オブジェクトの値( `{ name: "Taro Yamada" }` )
* ビュー(UI) = HTML
  * 例: input要素( `<input type="text" name="name">` )&#x20;

と読み替える事が出来ます。MVVMを細かく分けると モデルからビュー(M->V)への片方向だけのデータ反映を想定した **単方向(One-way binding)バインディング** 、とモデルからビュー(M->V)、ビューからモデル(V->M)の双方向のデータ反映を **双方向(Two-way binding)バインディング** の2つに分けることができます。それぞれこのようなライブラリ/フレームワーク(以降、FW)での採用事例があります。

* 単方向(One-way)バインディング = **React**
* 双方向(Two-way)バインディング = **Angular / Vue.js**

ライブラリ/FWごとに設計思想・やりたい事が違うので、採用している手法に差が出ているのですが、ここではそれぞれの実装方式について、説明していこうと思います。

### 単方向(One-way)バインディングについて

これは **React** で主に採用されている仕組みです。[ドキュメント](https://reactjs.org/docs/thinking-in-react.html) にもちょっと記載があります。 **モデルからビュー** への反映のみを行います。逆の**ビューからモデル**への値の取得は自身で処理を書く(Reactの場合には `setState()` と呼ばれるものを使う)必要があります。

![単方向(One-way)バインディングのイメージ](https://2587240623-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M494Pr3hMOi0R4_iECc%2F-M72MfxtbKZjj5YBNVlE%2F-M72x-CcEc5re5b8sh0d%2Fone-way.png?alt=media\&token=323751cd-0568-4e10-80b5-1ed052175e3d)

基本的な仕組みとしては以前に書いた以下の **Tab(タブ) - JS動的生成版** の実装例が近い内容なので、気になる方は改めて見てみてください。**JSのモデルを元にHTMLを生成し、それをブラウザに反映する。**&#x3068;いう考え方です。この **反映** の部分を効率良く行う仕組み(差分適用の仕組み)を [VirtualDOM(仮想DOM)](https://reactjs.org/docs/faq-internals.html) と呼びます。(Reactを起点としつつ色々なライブラリで内部的に採用されている仕組みです)

{% content-ref url="../manual/learn-from-examples-basis/tab" %}
[tab](https://docs-f.mix-soft.com/manual/learn-from-examples-basis/tab)
{% endcontent-ref %}

### 双方向(Two-way)バインディングについて

これは **Vue.js(とAngular。元々はAngularJS(\~v1系)の頃に出てきたもの)** で採用されているものです。 [Vueのドキュメント](https://vuejs.org/v2/guide/forms.html) にも記載があります。**モデルからビュー、ビューからモデル** の双方向での反映をやってくれるので、使う側は対応するinput要素に独自の `v-model="model.name"` といった構文を書くことで、 `JSのmodel.name <-> input要素のvalue`  の間のデータの同期を行ってくれます。フォーム内の入力欄が多いサイト(例: ECサイトの個人情報の登録フォーム)ではこの双方向バインディングの方が前述の単方向バインディングと比べてシンプルに実装が出来ます。

![双方向(Two-way)バインディングのイメージ](https://2587240623-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M494Pr3hMOi0R4_iECc%2F-M72MfxtbKZjj5YBNVlE%2F-M72y60NVZcU2rTVFPF9%2Ftwo-way.png?alt=media\&token=e09d779f-5cfc-4527-8937-f3d0273dcf71)

次の章では双方向(Two-way)バインディングを実装しつつ、より細かい内容を説明していきます。
