レスポンシブ原則をシミュレートするための基礎コードの 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 の時間保持問題に関する簡単な分析

推薦する

Mysql の mysql.user ユーザー テーブルの詳細な説明

MySQL は、異なるユーザーに異なる権限を割り当てることができるマルチユーザー管理データベースであ...

UbuntuでOpenCVをコンパイルしてインストールする方法

opencv2 の簡単なインストール: conda インストール --channel https:/...

MySQL Shell import_tableデータインポートの実装

目次1. import_tableの紹介2. データのロードとテーブル関数のインポートの例2.1 L...

Vueでパスワードの表示と非表示機能を実装するアイデアを詳しく解説

効果: アイデア:入力タイプ属性を使用して、タイプ値がテキストの場合はパスワードを表示し、タイプ値が...

nuxt.js 複数の環境変数の設定

目次1. はじめに2. シナリオ3. 環境を整える3.1 環境変数の挿入4. 最後に1. はじめに一...

Docker Swarm 外部検証ロードバランシングが機能しない場合の解決策

問題の説明Centos7 をローカルにインストールして 3 つの仮想マシンを作成し、Swarm クラ...

表のセル間の境界線/区切り線を非表示にする方法

上の境界線のみを表示する <table frame=above>下の境界線のみを表示する...

Vue マルチページ構成の詳細

目次1. 複数ページの違い2. SPAとMPA 3. Vue Cli スキャフォールディング構成1....

vue-cli でレスポンシブ レイアウトを実装する方法

フロントエンド開発を行うと、PCとモバイル端末の適応に必然的に直面することになります。このような問題...

XHTML チュートリアル、XHTML の基礎を簡単に紹介します

<br />この記事では、XHTMLとXHTMLの基礎知識について簡単に紹介します。 X...

フローティング要素が親要素の高さを崩す原因と解決策の詳細な説明

フローティング要素は、親要素の高さを縮小します。要素を float float:left/right...

一般的な Nginx のテクニックと例の概要

1. 複数サーバーの優先順位たとえば、各サーバー ブロックがポート 80 をリッスンする場合、www...

Vue でのキープアライブコンポーネントの使用例

問題の説明(キープアライブとは何か)キープアライブ 名前の通り、アクティブな状態を維持します。誰が活...

Apache ポートに基づいて仮想ホストを作成する例

apache: ポートに基づいて仮想ホストを作成する仮想ホスト(a、b、c)の作成を例に挙げます1)...

2017 最新バージョンの Windows インストール MySQL チュートリアル

1. まず、MySQL の公式サイトから最新バージョンの MySQL をダウンロードします。リンクを...