手動で簡単な双方向のデータバインディングMVVMを実装するには

データバインディング

  一般的に結合データは、データを参照するビューを表示します。現在、遠位フレームモードは、二重結ば達成するために使用されるMVVM。いくつかの一般的な方法があります。

  1.  パブリッシュおよびサブスクライブ
  2.    ngの汚れチェック
  3.    データハイジャック

  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 
        } 
    })
 </スクリプト>

 

 もちろん、これは詳細、アイデアの主に研究を考慮していない、単純な実現です。

 

    

  

  

おすすめ

転載: www.cnblogs.com/wjyz/p/11419073.html