ホームページ > ウェブフロントエンド > Vue.js > Vue で $set がどのように実装されるかについて話しましょう。

Vue で $set がどのように実装されるかについて話しましょう。

青灯夜游
リリース: 2022-12-15 21:26:32
転載
3063 人が閲覧しました

Vue で $set がどのように実装されるかについて話しましょう。

Vue2 の応答性の中核は ES5 の Object.defineProperty を使用することであるため、日常の開発では $set も非常に実用的な API です。 、配列の添字を直接変更して配列を変更したり、オブジェクトに新しいプロパティを追加したりすると、Object.defineproperty はデータの変更を監視できません。このとき、誰もが $set を使用します。変更された操作も応答するようになりました。それはわかっていますが、その理由もわかります。次に、Vue の $set がどのように実装されているかを見てみましょう。 [関連する推奨事項: vuejs ビデオ チュートリアル Web フロントエンド開発 ]

アプリケーション シナリオ

 let dataArr = ["item1"];
 let dataObject = {
      name: "ccs"
    };

    dataArr[2] = "item2";
    dataObject.age = 22;
    响应失败,页面没有显示更新新增的数据

    this.$set(this.dataArr,2,'item2')
    this.$set(this.dataObject,'age',22)
    响应成功,页面显示更新新增的数据
ログイン後にコピー

セット実装

次に、Vue での $set の定義を見てみましょう

function set(target: Array<any> | Object, key: any, val: any): any {
  if (
    process.env.NODE_ENV !== "production" &&
    (isUndef(target) || isPrimitive(target))
  ) {
    warn(
      `Cannot set reactive property on undefined, null, or primitive value: ${(target: any)}`
    );
  }
  if (Array.isArray(target) && isValidArrayIndex(key)) {
    target.length = Math.max(target.length, key);
    target.splice(key, 1, val);
    return val;
  }
  if (key in target && !(key in Object.prototype)) {
    target[key] = val;
    return val;
  }
  const ob = (target: any).__ob__;
  if (target._isVue || (ob && ob.vmCount)) {
    process.env.NODE_ENV !== "production" &&
      warn(
        "Avoid adding reactive properties to a Vue instance or its root $data " +
          "at runtime - declare it upfront in the data option."
      );
    return val;
  }
  if (!ob) {
    target[key] = val;
    return val;
  }
  defineReactive(ob.value, key, val);
  ob.dep.notify();
  return val;
}
ログイン後にコピー

ソースコードでは、まず set の対象が 未定義 かつ 基本型#であるかどうかを判断します。 ##それが の場合、未定義 または 基本タイプ がエラーを報告する場合、
ユーザーは未定義および基本タイプに設定すべきではないため、then は、ターゲットが配列であるかどうかを判断します。キーは正当なインデックスですか? 正当なインデックスとは、0 以上の値を持つ整数を指します。
両方の条件が true の場合、splice メソッドを呼び出します。
配列を挿入または変更するターゲット配列 , ここでの
splice は通常の splice ではありません。 はスプライス#です## Wang Wei の詩の、vue プロキシによって書き換えられたスプライスです。配列実装応答

$set は、配列変更応答を一部として実装します。エージェントによって書き換えられた配列メソッド 次に、具体的な実装を見てみましょう

const arrayProto = Array.prototype
export const arrayMethods = Object.create(arrayProto)

const methodsToPatch = [
  &#39;push&#39;,
  &#39;pop&#39;,
  &#39;shift&#39;,
  &#39;unshift&#39;,
  &#39;splice&#39;,
  &#39;sort&#39;,
  &#39;reverse&#39;
]
function def(obj, key, val, enumerable) {
    Object.defineProperty(obj, key, {
        value: val,
        enumerable: !!enumerable,
        writable: true,
        configurable: true
    });
}
methodsToPatch.forEach(function (method) {
  const original = arrayProto[method]
  def(arrayMethods, method, function mutator (...args) {
    const result = original.apply(this, args)
    const ob = this.__ob__
    let inserted
    switch (method) {
      case &#39;push&#39;:
      case &#39;unshift&#39;:
        inserted = args
        break
      case &#39;splice&#39;:
        inserted = args.slice(2)
        break
    }
    if (inserted) ob.observeArray(inserted)
    ob.dep.notify()
    return result
  })
})
ログイン後にコピー
vue のエージェントは、

splice

だけでなく、7 つのメソッドも書き換えます。 ##プッシュ、ポップ、シフト、シフト解除、スプライス、ソート、リバース。 まず、const result =original.apply(this, args)元の配列のメソッドを実行してその値を取得し、配列に値を追加するかどうかを決定します 新しく追加された値も実装されます 応答性,最後のステップこの配列の
_ob_object を取得します Pair _ob_ の dep が配布および更新されます。 vue の応答性について詳しく知りたい場合は、以前の記事をご覧ください。
面接官から Vue2 の応答性の原則について質問されました。どう答えましたか? - Nuggets (juejin.cn)
オブジェクト実装応答

$set

下半分のロジックは、オブジェクト応答を処理するために使用されます。

  if (key in target && !(key in Object.prototype)) {
    target[key] = val;
    return val;
  }
  const ob = (target: any).__ob__;
  if (!ob) {
    target[key] = val;
    return val;
  }
  defineReactive(ob.value, key, val);
  ob.dep.notify();
  return val;
ログイン後にコピー
まず、プロパティを判断します。ターゲット オブジェクトを直接返してロジックを終了すると、 vue は元々存在しないプロパティのみを追加するため、応答の喪失

,
たとえば、obj={} obj.name='ccs',
vue とすると、初期化中にデータ内のすべての属性が応答可能になります。値がオブジェクトまたは配列の場合、新しい Observer インスタンスは __ob__ に保存されます。
vue の応答性について詳しく知りたい場合は、以前の記事をチェックしてくださいインタビュアー Vue2 の応答性の原則について質問しましたが、どう答えますか? - Nuggets (juejin.cn)
このオブジェクトの _ob_ を取得して判断します。存在しない場合は、vue によって初期化されていない 通常のオブジェクトであることを意味します。
レスポンス Formula オブジェクトの それ以外の場合は、defineReactive を介して属性に get メソッドと set メソッド を手動で追加してレスポンスを実装します、その後手動で呼び出します # # in dep #notify()更新を公開します。
概要vue の $set メソッドは、配列とオブジェクトを基本的に同じ方法で処理し、新しい値への応答を追加し、手動でディスパッチ更新をトリガーします。

(学習ビデオ共有:

vuejs 入門チュートリアル

基本プログラミング ビデオ

)

以上がVue で $set がどのように実装されるかについて話しましょう。の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:juejin.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート