Vue データ内のプロパティをランダムに変更すると、ビューは更新されますか?

Vue データ内のプロパティをランダムに変更すると、ビューは更新されますか?
  • インタビュアー: Vue のソースコードを読んだことはありますか?
  • 応募者:あります。
  • インタビュアー: では、 Vue dataのプロパティを変更すると、ビューは更新されますか?
  • 候補者:いいえ。
  • インタビュアー:なぜですか?
  • 候補: プロパティがテンプレートで使用されていない場合は、ビューを更新する必要はなく、頻繁に更新するとパフォーマンスが低下します。
  • インタビュアー: このソリューションを Vue でどのように実装しますか?
  • 候補: インスタンスの初期化中に、 Object.definePropertyを使用してデータ内のプロパティを監視します。プロパティがtemplateで使用されている場合、それらは Dep クラスによって収集され、プロパティが変更されると、notify が呼び出されてビューが更新されます。
  • インタビュアー: テンプレートでどの属性が使用されているかはどのようにしてわかりますか?
  • 候補者: 何だこれ。 。 。よく分かりません。説明していただけますか?
  • インタビュアー: では、簡単に説明させてください。

まずは簡単なdemoを書いてみましょう。データには 4 つの属性 a、b、c、d があり、テンプレートでは a と b のみが使用されます。 a と b だけが Dep に電話して回収するかどうかを確認します。

新しいVue({
  el: '#app',
  データ() {
    戻る {
      a: 1、
      b: 2,
      c: 3,
      d: 4,
    };
  },
  作成された() {
    コンソールにログ出力します。
    this.b = 'aaa';
  },
  テンプレート: '<div>Hello World{{a}}{{b}}</div>',
});


Vueinstance/state.jsでは、各属性をプロキシするためにプロキシが使用されます。

定数キー = Object.keys(データ)
  定数プロパティ = vm.$options.props
  const メソッド = vm.$options.methods
  i = キーの長さとする
  (i--) {
    定数キー = キー[i]
    もしprops && hasOwn(props, key) であれば
      process.env.NODE_ENV !== 'production' && 警告(
        `データ プロパティ "${key}" はすでにプロパティとして宣言されています。` +
        `代わりにプロパティのデフォルト値を使用してください。`,
        仮想
      )
    } そうでなければ (!isReserved(key)) {
      //プロキシオブジェクトのプロパティ proxy(vm, `_data`, key)
    }
  }
  // データを観察する
  観察(データ、true /* asRootData */)


データ内の各属性をハイジャックするには、defineReactive を使用します。

観察(データ、true /* asRootData */);

// 観察する
定数キー = Object.keys(obj);
(i = 0 とします; i < keys.length; i++) {
  Reactive を定義します (obj、キー [i])。
}

// リアクティブを定義する
Object.defineProperty(obj, キー, {
  列挙可能: true、
  設定可能: true、
  取得: 関数reactiveGetter() {
    const value = getter ? getter.call(obj): val;
    // 重要なポイントはここです。後でテンプレートで属性が使用される場合、reactiveGetter関数が実行されます // Depクラスによって収集されます if (Dep.target) {
      console.log(`${key} プロパティは Dep クラスによって収集されます`)
      依存関係
      if (childOb) {
        childOb.dep.depend();
        Array.isArray(値)の場合{
          依存配列(値);
        }
      }
    }
    戻り値;
  },
  設定: 関数reactiveSetter(newVal) {
    const value = getter ? getter.call(obj): val;
    /* eslint は自己比較を無効にします */
    if (newVal === 値 || (newVal !== newVal && 値 !== 値)) {
      戻る;
    }
    if (セッター) {
      // 計算されたセット関数は次のとおりです。setter.call(obj, newVal);
    } それ以外 {
      val = 新しいVal;
    }
    childOb = !shallow && observe(newVal);
    // プロパティを変更すると、notify を呼び出してビューを非同期的に更新します。dep.notify();
  },
});

$mountを実行してビューをマウントします

(vm.$options.el)の場合{
  vm.$mount(vm.$options.el);
}


$mount は Vue プロトタイプを呼び出すメソッドです。重要な点は最後の文 mount.call(this, el, hydrating) です。

Vue.prototype.$mount = 関数 (
  el?: 文字列 | 要素、
  水分補給?: ブール値
): 成分 {
  el = el && クエリ(el);

  const オプション = this.$options;
  // template/el を解決し、レンダリング関数に変換します
  /**
   * レンダリング関数が存在するかどうかを確認しますか?存在しない場合は、テンプレートを解析します。テンプレート* Vue がページをレンダリングする場合、2 つの方法があります: 1. テンプレート、2. レンダリング。最終的には、すべてのテンプレート クラスをレンダリングを使用してレンダリングする必要があります。*/
  if (!options.render) {
    テンプレートを options.template とします。
    if (テンプレート) {
      if (typeof テンプレート === '文字列') {
        (template.charAt(0) === '#')の場合{
          テンプレート = idToTemplate(テンプレート);
          /* イスタンブールは無視します */
          process.env.NODE_ENV !== 'production' && !template) の場合 {
            警告(
              `テンプレート要素が見つからないか空です: ${options.template}`,
              これ
            );
          }
        }
      } それ以外の場合 (template.nodeType) {
        テンプレート = template.innerHTML;
      } それ以外 {
        process.env.NODE_ENV !== 'production' の場合 {
          warn('無効なテンプレートオプション:' + template, this);
        }
        これを返します。
      }
    } そうでなければ (el) {
      // テンプレートが存在しない場合は、デフォルトの HTML テンプレートを作成します。 template = getOuterHTML(el);
    }
  }
  // Vue.prototype.$mount を書き換え、最後にキャッシュされた mount メソッドを呼び出して $mount のマウントを完了します。 return mount.call(this, el, hydrating);
};

ここで、mount は mountComponent(this, el, hydrating) メソッドを呼び出し、mountComponent は _render 関数を実行し、最後に _render は render を呼び出して vnode を生成します。

const { render, _parentVnode } = vm.$options;
vnode = render.call(vm._renderProxy、vm.$createElement);


最後の図は、 render関数がdemotemplateをレンダリングしていることを示しています。最終的には、2 つの属性 a と b のみが Dep クラスによって収集されます。

記事に間違いがありましたらご指摘いただければ、引き続き改善させていただきます。ありがとうございます。ソースコードをデバッグする必要がある場合は、ここをクリックして readme に従ってください。希望の星

これで、Vue データのプロパティを変更してビューを更新する方法に関するこの記事は終わりです。より関連性の高い Vue データ コンテンツについては、123WORDPRESS.COM で以前の記事を検索するか、以下の関連記事を引き続き参照してください。今後も 123WORDPRESS.COM を応援していただければ幸いです。

以下もご興味があるかもしれません:
  • vue data が関数である理由をご存知ですか?
  • vueはデータの問題を修正し、リアルタイムで操作を表示します
  • Vueサブコンポーネントはデータを変更したり操作を呼び出したりします
  • Vueデータ変数が相互に割り当てられた後のリアルタイム同期の解決手順

<<:  判定条件を使用してCSSファイルをインポートする

>>:  CSS を使用してボックスを水平方向と垂直方向に中央揃えする方法 (8 つの方法)

推薦する

アイデア展開Tomcatサービス実装プロセス図

まずプロジェクトの成果物を構成するスタートアップ項目の設定 Tomcatサービスを作成する開始したい...

Tomcat の maxPostSize 設定に関する問題と注意事項

1. maxPostSize を設定する理由は何ですか? tomcat コンテナには送信データのサイ...

VueはPCで写真をアップロードする機能を実現

この記事の例では、PC上で写真アップロード機能を実現するためのVueの具体的なコードを参考までに共有...

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

MySQL のデフォルトの時間タイプ (datetime と timestamp) の精度は秒です。...

JSONObject の使用方法の詳細な説明

JSONObject は単なるデータ構造であり、JSON 形式のデータ構造 ( key-value構...

Docker で Oracle 11g イメージ構成をプルダウンする際の問題を分析する

1. イメージをプルするdocker pull レジストリ.cn-hangzhou.aliyuncs...

MySQLの関連ロックについての簡単な理解

この記事は主にInnoDBのロックに関する知識を素早く理解してもらうことを目的としています。 Roc...

シンプルなカレンダー効果を実現する JavaScript コード

この記事では、シンプルなカレンダー効果を実現するためのJavaScriptの具体的なコードを参考まで...

VUE ユニアプリライフサイクルに関する簡単な説明

目次1. アプリケーションライフサイクル2. ページのライフサイクルコンポーネントライフサイクル要約...

Angularプロジェクトにおける共有モジュールの実装の詳細な説明

目次1. 共有共通モジュール2. 共有マテリアルモジュール3. 共有確認ダイアログ1. 共有共通モジ...

React を使って小さなプログラムを書くための Remax フレームワークのコンパイル プロセス分析 (推奨)

Remax は、実行時に構文制限のないソリューションを採用した React を使用して小規模なプロ...

CSS リスト モデルでのマーカー タグの使用

この記事では主に、 list-itemの下にある::master疑似要素、 list-style-i...

Linux の daily_routine サンプルコードの詳細な説明

まずサンプルコードを見てみましょう: #/bin/bash cal 日付 -u echo "...

MySQL 8.0.15 winx64 のインストールと設定方法のグラフィックチュートリアル

この記事では、MySQL 8.0.15のインストールと設定方法を参考までに紹介します。具体的な内容は...

Vue要素ツリーコントロールに点線を追加する詳細な説明

目次1. 成果を達成する2. 実装コード3. その他の実装要約する1. 成果を達成する 2. 実装コ...