データバインディング
一般的に結合データは、データを参照するビューを表示します。現在、遠位フレームモードは、二重結ば達成するために使用されるMVVM。いくつかの一般的な方法があります。
- パブリッシュおよびサブスクライブ
- ngの汚れチェック
- データハイジャック
VUEは、その後、組み合わせをサブスクライブデータの乗っ取りや公開を使用しています。対応する機能を取得し、取得を結合し、設定することによりデータを設定する際に使用されるデータをトリガすることができ、達成するObject.definePropertyハイジャックです。
実現
だから我々は、データの変化を観察リッスンするリスナーを必要としています。データの変更は、私たちはビューを更新するために、ウォッチャーの加入者を必要とするとき、我々はまた、ビューを初期化するためのコマンドと命令を解析するパーサをコンパイルする必要があります。
-
- リスナーを守ってください。データの変更を監視し、加入者に通知
- ウォッチャー加入者:ビューを更新し、データの変更を受け取ります
- パーサをコンパイル:加入者を結合、テンプレートを初期化するコマンドの構文解析
観察する
複数のウォッチャーがあってもよいので、各モニタのデータ属性は、コンテナを格納する必要があります。
関数サブ(){ これは .subs = []; } Sub.prototype = { {(サブ)を追加し 、この.subs.push(サブ)。 }、 トリガー(){ この .subs.forEach(副=> { sub.update(); }) } }。 Sub.target = nullを。 この関数は、{(データ)を観察し た場合(typeof演算データを== 'オブジェクト' ||データ!)のリターンを。 Object.keys(データ).forEach(項目 => { せヴァル = データ[アイテム]。 聞かせてサブ = 新しいサブ(); Object.defineProperty(データ、アイテム、{ 列挙:真、 設定:偽、 取得(){ 場合(Sub.target){ sub.add(Sub.target); } 戻りヴァルを; } 設定(newValに){ ヴァル = newValに、 sub.trigger(); } }) }) }
ウォッチャー
属性対応ウォッチャーは、アップデート機能を実行するために、サブコンテナ、属性の変更を加えました。
関数ウォッチャー(VM、小道具、コールバック){ この .vm = VM。 この .prop = 小道具。 この .callback = コールバック。 Sub.target = この; valを聞かせて = この.vmを$データ[小道具]。 Sub.target = nullを。 この .vaule = valの; } Watcher.prototype.update = 関数(){ newValueにせ = この .vmを$データ[ この.prop]。 もし(この .VALUE ==!newValueに){ この .VALUE = newValueに。 この .callback.call(この.vm、newValueに)。 } }
コンパイル
ドムは、命令や初期化テンプレートを取得ウォッチャー更新にビューを追加します。
関数コンパイル(VM){ この .vm = VM。 この .EL = VM $エル。 この.INIT(); } Compile.prototype.init = 関数(){ せ断片 = document.createDocumentFragment()。 子供を聞かせて = この.el.firstChild。 一方、(子){ fragment.append(子)。 子 = この.el.firstChild。 } のchildNodesせ =のfragment.childNodesと、 Array.from(のchildNodes).forEach(ノード => { 場合(node.nodeType === 1 ){ ATTRSのせ =のnode.attributesを、 Array.from(ATTRS).forEach(ATTR => { せ名 = attr.nodeName ; 場合(名前は=== 'V-モデル' ){ プロパせ = attr.nodeValueと、 値せ = この; .vm $データ[プロパ] node.value = 値を、 新たなウォッチャーの(この .vm、小道具、ヴァル=> { node.value = ヴァル。 }); node.addEventListener( '入力'、E => { newValにせ = e.target.valueを、 場合!(値== newValに){ この .vm $データ[プロパ] =。newValに; } }) } }) } せREG = /\{\{(.*)\}\}/ 。 テキストましょう = node.textContentを。 もし(reg.test(テキスト)){ 小道具ましょう = RegExpオブジェクトを$ 1 ; valを聞かせて = この.vmを$データ[小道具]。 node.textContent = ヴァル; 新しいウォッチャー(この .vm、プロップ、ヴァル=> { node.textContent = ヴァル; }); } }) この.el.appendChild(断片)。 }
ここでは、基本的な考え方は、単にV-modelコマンドを達成するために、完成されて実装されています。
最後に、完全なMVVMアップになることができ、ウォッチャーを観察してコンパイルします。
<DIV ID = "アプリケーション"> の<div> {{ヴァル}} </ div> の<input type = "テキスト" ID = "入力" Vモデル= "ヴァル"> </ div> <スクリプト> 関数MyVue(オプション){ この $オプション=。オプション; この。$エル= options.el。 この。$データ= options.data。 この.INIT(); } MyVue.prototype.init = 関数(){ (観測この$データ。); 新しいコンパイル(この); }。新しいMyVue({ EL:のdocument.getElementById( 'アプリ' )、 データ:{ ヴァル: 123 } }) </スクリプト>
もちろん、これは詳細、アイデアの主に研究を考慮していない、単純な実現です。