ホームページ  >  記事  >  ウェブフロントエンド  >  vv ソースコードを一緒に学び理解する

vv ソースコードを一緒に学び理解する

零下一度
零下一度オリジナル
2017-06-26 09:50:481408ブラウズ

vue の公式 Web サイトによると、vue は mvvm フレームワークであり、レスポンシブであることがわかります。その意味をより深く理解するために、簡単な mvvm 学習デモを実装しました。以下の皆さんと共有し、一緒に議論してください。

1. mvvm には少なくともコンテンツ

  1. 命令セット (テキスト、モデルなど) が含まれています。

  2. データ モデル、ビューと対話するデータ

  3. コンポーネントのサポート: つまり、 HTML コードの一部の動的更新

2. 私の実装

1. 変数の定義と watch の実装

var directives = {}; //指令集合var vNodes = new Array(); //解析的Dom集合var dataModel = {
    name:"name",
    title: "title"}; //数据Modelvar Watch = {
    isInit: false,
    watchs: new Array(),
    run: function(newValue, expOrfn){ var self = this;if(!self.isInit){
            expOrfn.call(vModel);
        }this.watchs.map(function(data,index){
            data.nodes.map(function(d,i){if(self.isInit){
                    d.directive.init(newValue, d, data); //绑定初始化值, 以及初始化一些事件}else{
                    d.directive.update(newValue, d, data); //只更新值,此时run的调用来值value-set                }
            });
        });
        
        self.watchs = [];
    },
    push:function(watch){this.watchs.push(watch);
    }
} //任务管理

説明:

  1. Watch の Push メソッドは依存関係を追加するために使用されます。依存関係を実行するには、実行が完了した後、現在の依存関係コレクションをクリーンアップする必要があります。 vueでの依存関係の収集はdepで完結し、watchでタスク管理を提供します(正しく理解できているかわかりません)

2.命令の定義

directives.text = { 
    init: function(value, vNode){
        vNode.elm.textContent = value;
    },
    update: function(value, vNode){
        vNode.elm.textContent = value;
    }
}//需要响应事件的怎么办directives.model ={ 
    init: function(value, vNode, _watch){
        vNode.elm.value = value; //判断自己发生的改变,不应该再改变自己 vNode.elm.addEventListener('keyup',function(evt){
            vNode.model[_watch.key] = vNode.elm.value;
        }); 
    },
    update:function(){

    }   
}

手順:

  1. デモの学習例なので、textとmodelの2つの簡単な仕様だけを定義しています。 text:はデータの表示に使用され、modelは入力(入力ボックス)の応答に使用されます

3. vModel の生成

//转换vModel,暂支持一级var properties = Object.getOwnPropertyNames(dataModel);var vModel = {}, formSetting = false;for( var index in properties){ 
    (function refreshData(_index){var key = properties[_index];var property = Object.getOwnPropertyDescriptor(dataModel, key);var setter = property.set;var getter = property.get;var _val = property.value;var _getter = function(){var val = getter ? getter.call(vModel) : _val;//收集依赖,与watch要分开            Watch.push({
                key: key,
                nodes: vNodes.filter(function(data,index){return data.modelKey == key ? true : false;
                }),
                getter: _getter
            });return val;
        };
        Object.defineProperty(vModel, key, {
            configurable: true,
            enumerable: true,
            set: function(value){if(setter){
                    setter.call(vModel, value);
                } //处理依赖                Watch.run(value, _getter);//this.value = value;            },
            get: _getter

        })
    })(index);
}

説明:

  1. vModel は dataModel に基づいて生成されます。つまり、各属性の get メソッドと set メソッドがカスタマイズされており、es6 のプロキシを使用して実装することもできます (Are)そうです)。

  2. 属性を設定するとき、依存関係を収集するために最初に get メソッドが呼び出されます。コンビニエンス値を変更すると、影響を受けるすべてのコンテンツを変更できます。

4. dom を vNode に解析する

//解析vNodesvar app = document.getElementById('app');
app.childNodes.forEach(function(data,index){if(data.nodeType != 1) return;var hv = data.getAttribute('data-hv');var hvs = hv.split(',');
    hvs.forEach(function(item,row){var keyValue = item.split(':'); //vNode对象上一定要有model,这是方便vNode相应时候的找vModel        vNodes.push({
            directive: directives[keyValue[0]],
            modelKey: keyValue[1],
            model: vModel,
            elm: data
        });
    });
});

説明:

  1. これは dom 上の data-hv で指定された命令を収集するだけなので、vNode に解析されるというのは突飛です。 、要素、vModel などはオブジェクトを形成し、vModel の各属性の get メソッドが依存関係を収集するときに参照するために vNode に保存されます。

5. 最初の初期化

//调用所有的get一次Watch.isInit = true;var _keys = Object.getOwnPropertyNames(vModel);
_keys.map(function(key,data){var data = vModel[key];
    Watch.run(data); 
});
Watch.isInit = false;

手順:

  1. ここでは、各 get がアクティブに実行され、その後 watch.run メソッドが実行されます。

  2. ここでの設計と実装は、vue の考えと一致していないように感じます。もしこれを見た人がいたら、アドバイスと指導をお願いします。

6. 解析されたドム

rreee

以上がvv ソースコードを一緒に学び理解するの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。