レスポンシブ原則をシミュレートするための基礎コードの Vue 実装の例

レスポンシブ原則をシミュレートするための基礎コードの Vue 実装の例

Vue の基本構造の全体的な分析を下の図に示します。(注: 完全なコードの github アドレスは https://github.com/1512955040/MiniVue です)


上の図では、最小限の vue の全体構造をシミュレートしています。まず、データ内のメンバーを vue インスタンスに注入し、それらを getter/setter に変換する役割を持つ vue タイプを作成します。オブザーバーの役割は、データのハイジャック、データ内の属性の監視、データが変更された場合の最新の値の取得、および dep への通知です。コンパイラの役割は、各要素内の命令と差分式を解析し、対応するデータに置き換えることです。 Dep の役割は、オブザーバーを追加し、データが変更されたときにすべてのオブザーバーに通知することです。 Watcher 内にはビューの更新を担当する Update メソッドがあります。コードでこれらを 1 つずつ実装してみましょう。

1.Vue.js の機能:

1-1は初期化パラメータ(オプション)の受信を担当します。

1-2は、データ内の属性をvueインスタンスに注入し、それをゲッター/セッターに変換する役割を担っています。

1-3は、データ内のすべての属性の変更を監視するためにオブザーバーを呼び出す責任があります。

1-4は、命令/差分式を解析するためにコンパイラを呼び出す役割を担う。

クラス図の構造は次のとおりです。

上の図に示すように、vue クラスには $options、$el、$data という 3 つの属性があります。これらの 3 つの属性は、コンストラクターで渡されるパラメーターを記録します。 _proxyDataはvueクラスのメソッドです

したがって、_ で始まるメンバーはプライベート メンバーです。このメソッドの機能は、データ内のプロパティをゲッターとセッターに変換し、Vue インスタンスに注入することです。

クラス Vue{
    コンストラクタ(オプション) {
        //1. 属性を通じてオプションにデータを保存します this.$options = options || {}
        this.$data = オプション.data || {}
        this.$el = typeof options.el === 'string' ? document.querySelector(options.el) : options.el
        //2. データのメンバーをゲッターとセッターに変換し、vue インスタンスに注入します this._proxyData(this.$data)
        //3. データの変更を監視するためにオブザーバーオブジェクトを呼び出す new Observer(this.$data)
        //4. コンパイラオブジェクトを呼び出して命令と差分式を解析する new Compiler(this)
    }
    //Vue のプロパティをゲッターとセッターに変換し、Vue に注入します。instance_proxyData(data){
        //dataObject.keys(data).forEach(key=>{ 内のすべての属性を走査します。
          //データ属性をvueインスタンスにグローバルに注入する Object.defineProperty(this, key, {
              列挙可能:true、
              設定可能:true、
              得る(){
                データを返す[キー]
              },
              set(新しい値){
                if(newValue===データ[キー]){
                    戻る 
                }
                データ[キー]=新しい値
             }
        })    
      })
    }
}

2.Observer.js 関数 (データハイジャック):

2-1 データオプションの属性をレスポンシブデータに変換する責任

2-2 データ内のプロパティもオブジェクトです。プロパティをレスポンシブデータに変換します。

2-3 データが変更されたときに通知を送信する

クラス図の構造は次のとおりです。

上の図に示すように:

walk メソッドはデータ内のすべての属性をトラバースするために使用され、defineReactive はレスポンシブ データを定義するために、つまり、defineReactive メソッドを呼び出して属性をゲッターとセッターに変換するために使用されます。

クラスオブザーバー{
    コンストラクタ(データ) {
        this.walk(データ)
    }
    //walkメソッドはデータ内のすべての属性を走査します walk(data) {
        //1. データがオブジェクトかどうかを判定する if(!data || typeof data !=='object'){
            戻る 
        }
        //2. データオブジェクトのすべてのプロパティを走査します。Object.keys(data).forEach(key=>{
            this.defineReactive(データ、キー、データ[キー])
        })
    }
    //defineReactivece メソッドは、プロパティをゲッターとセッターに変換するためのレスポンシブ データを定義します。
    定義Reactive(オブジェクト、キー、値) {
        それを=これとする
        // 依存関係の収集と通知の送信を担当します。let dep = new Dep()
        // val がオブジェクトに渡された場合、オブジェクトのプロパティに getter メソッドと setter メソッドを追加します this.walk(val)
        オブジェクト.defineProperty(obj,キー,{
            列挙可能:true、
            設定可能:true、
            得る(){
                // 依存関係を収集 Dep.target && dep.addSub(Dep.target)
                戻り値
            },
            set(新しい値){
                if(newValue==val){
                    戻る 
                }
                val=新しい値
                // 属性をオブジェクトに再割り当てする場合は、オブジェクトの属性に getter メソッドと setter メソッドを再度追加します // 例: 履歴データ vm.msg="Hello World" 変更後 vm.msg={a:'Hwllo World'}
                // このメソッドを再度呼び出して、ゲッターメソッドとセッターメソッドを vm.msg.a に再度追加します that.walk(newValue)
                //通知を送信する dep.notify()
            }
        })
    }
}

3. Compiler.js 関数:

3-1 テンプレートのコンパイルと命令/差分式の解析を担当

3-2 ページの最初のレンダリングを担当

3-3 データが変更されたときにビューを再レンダリングする

クラス図の構造は次のとおりです。

上の図に示すように:

el はコンストラクタによって渡される options.el、vm は vue のインスタンスであり、以下はすべて DOM を操作するための vm のメソッドです。コンパイルメソッドはDOMオブジェクトのすべてのノードを走査し、

これらのノードがテキストノードであるかどうかを判定します。テキストノードの場合は、差分式を解析します。要素ノードの場合は、命令を解析します。isTextNodeメソッドとisElementNodeメソッドは、テキストノードであるか、

要素ノードです。 compileElement メソッドと compileText メソッドは、異なる式とディレクティブを解析します。 isDirective メソッドは、要素属性がディレクティブであるかどうかを判断します。

4.Dep.js の機能:

4-1 依存関係を収集し、ウォッチャーを追加する

4-2 すべての観察者に通知する

上の図に示すように:

Vue のレスポンシブ機構では、データの変更に応答するためにオブザーバー モードが使用されます。Dep の役割は、依存関係を収集し、getter メソッドで依存関係を収集し、setter メソッドで依存関係を通知することです。

レスポンシブプロパティには、プロパティに依存するすべての場所を収集する役割を持つDepオブジェクトがあります。プロパティに依存するすべての場所はウォッチャーオブジェクトを作成するので、

Depはプロパティに収集されたウォッチャーオブジェクトであり、setterメソッドを使用して依存関係を通知し、プロパティが変更されたときにnodifyメソッドを呼び出して通知を送信し、ウォッチャーオブジェクトを呼び出します。

更新方法。

クラスの構造は次のとおりです。

上の図に示すように:

subsはdep内のすべてのウォッチャーを格納する配列であり、addSubメソッドはウォッチャーを追加し、notifyメソッドは通知を発行します。

クラス Dep{
    コンストラクタ() {
        //すべてのオブザーバーを保存します this.subs=[]
    }
    // オブザーバーを追加 addSub(sub){
        if(sub && sub.update) {
            this.subs.push(サブ)
        }
    }
    //通知を送信するnotify(){
        this.subs.forEach(sub =>{
            サブ.更新()
        })
    }
}

5.Watcher.js の機能:

5-1 データの変更により依存関係がトリガーされると、depはすべてのWatcherインスタンスにビューを更新するように通知します。

5-2 自分自身をインスタンス化するときに、自分自身を dep オブジェクトに追加する

上の図に示すように:

データ内の各属性に対して Dep オブジェクトが作成されます。依存関係を収集する場合、すべてのオブジェクトのウォッチャーが dep オブジェクトの subs 配列に追加され、setter オブジェクトで通信が送信されます。

Dep オブジェクトの notification メソッドを呼び出して、関連付けられているすべてのウォッチャー オブジェクトにビューを更新するように通知します。

クラス図の構造は次のとおりです。

上の図に示すように:

更新オブジェクトはビューを更新し、cb コールバック関数はビューの更新方法を指定します。ビューを更新する場合、属性キー (データ内の属性名) が必要であり、oldvalue はキーに対応する値です。

クラスウォッチャー{
    コンストラクタ(vm,key,cb) {
        this.vm=vm
        //データ内の属性名 this.key=key
        //コールバック関数はビューの更新を担当します this.cb=cb
        //ウォッチャーオブジェクトをDepクラスの静的属性ターゲットに記録します
        依存先 = this
        //getメソッドをトリガーし、addSubが呼び出されます
        this.oldValue=vm[キー]
        依存関係ターゲット=null
    }
    // データが変更されたらビューを更新する update() {
        newValue = this.vm[this.key]とします
        if(this.oldValue === newValue){
            戻る
        }
        this.cb(新しい値)
    }
}

次の図は、全体的なプロセスをまとめたものです。

これで、Vue のシミュレートされたレスポンシブ原則の基盤となるコード実装の例に関するこの記事は終了です。Vue レスポンシブ原則に関するより関連性の高いコンテンツについては、123WORDPRESS.COM で以前の記事を検索するか、次の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM を応援していただければ幸いです。

以下もご興味があるかもしれません:
  • vue3.2 で追加された defineCustomElement の基本原理の詳細な説明
  • Vueデータ双方向バインディングの基本的な実装原則
  • Vue の基本的な実装原則の概要
  • Vue の基本原理についてどれくらい知っていますか?

<<:  Linux 上での MySQL データベースのリモート展開の詳細な手順

>>:  MySQL の時間保持問題に関する簡単な分析

推薦する

ReactでCSSスタイルを動的に変更する2つの方法の詳細な説明

最初の方法: デモとしてボタンをクリックしてテキストを表示または非表示にするクラスを動的に追加します...

startup.bat をダブルクリックすると Tomcat がクラッシュする問題の解決方法の詳細な説明

Tomcat を学習したばかりのプログラマーにとって、これはよくある間違いです。 1. 環境変数の問...

Ubuntu 20.04 に GitLab をインストールして設定する方法

導入GitLab CE または Community Edition は、主に Git リポジトリのホ...

mysql8.0.19 winx64バージョンのインストール問題を解決する

MySQL は、スウェーデンの会社 MySQL AB によって開発されたオープンソースの小規模なリレ...

Dockerコンテナが停止できない問題の解決方法

解決策は次のとおりです。 1. コンテナを強制削除する docker rm -f ジェンキンス2. ...

ウェブデザインとは何か

<br />元の記事: http://www.alistapart.com/articl...

Vueダイナミックフォームの詳細な応用

概要バックグラウンド管理システムには多くのフォーム要件があります。データをjson 形式で書き込み、...

CSSスタイルで実現されるHTML背景色のグラデーション効果

エフェクトのスクリーンショット:実装コード:コードをコピーコードは次のとおりです。 <!DOC...

MySQL ユーザー権限管理の分析例

この記事では、MySQL ユーザー権限管理の例について説明します。ご参考までに、詳細は以下の通りです...

MySQL 8.0.11 Community Green Edition の Windows 用インストール手順図

このチュートリアルでは、インストールに最新の MySQL コミュニティ グリーン バージョンである ...

Vueはランニングライトのシンプルな効果を実現

この記事では、マーキーのシンプルな効果を実現するためのVueの具体的なコードを参考までに共有します。...

React プロジェクトにおける axios カプセル化と API インターフェース管理の詳細な説明

目次序文インストール導入環境の切り替え傍受を要求するレスポンスインターセプションAPIの統合管理要約...

vue フロントエンド HbuliderEslint リアルタイム検証 自動修復設定

目次HBuilderX での ESLint プラグインのインストールカスタム eslint-js ル...

UbuntuでMySQLデータベースファイルディレクトリを変更する方法

序文同社の Ubuntu サーバーは、さまざまなシステムのディレクトリを異なる論理パーティションに配...