ホームページ  >  記事  >  ウェブフロントエンド  >  Vue2&vue3データ対応原理分析と手動実装(詳細例)

Vue2&vue3データ対応原理分析と手動実装(詳細例)

WBOY
WBOY転載
2021-12-22 18:25:282171ブラウズ

この記事では、vue2 と vue3 のデータ応答性の原則分析と手動実装に関する関連知識を提供します。データ応答性のビューとデータは自動的に更新されます。データが更新されると、データの変更を追跡するためにビューも自動的に更新されます。みんなが助けてくれることを願っています。

Vue2&vue3データ対応原理分析と手動実装(詳細例)

#データの応答性

#ビューとデータは自動的に更新され、データが更新されるとビューも自動的に更新されます
  • データの変更を追跡すると、データの読み取りまたは設定時に一部のハイジャック操作を実行できます
  • vue2 defineProperty を使用します
  • vue3 代わりにプロキシを使用します
  • defineProperty の使用

変更を追跡する方法

var obj = {}var age 
Object.defineProperty(obj, 'age', {
    get: function() {
        consoel.log('get age ...')
        return age    },
    set: function(val) {
        console.log('set age ...')
        age = val    }})obj.age =100 //set age ...console.log(obj.age)//get age ...

オブジェクト obj は、age 属性を取得するときにデータ ハイジャックの get メソッドを呼び出します

age 属性に値を割り当てるときに、set メソッドが呼び出されます


Object.defineProperty を使用してデータ応答を実装する方法?

function defineReactive(data) {
  if (!data || Object.prototype.toString.call(data) !== '[object Object]')
    return;
  for (let key in data) {
    let val = data[key];
    Object.defineProperty(data, key, {
      enumerable: true, //可枚举
      configurable: true, //可配置
      get: function() {
        track(data, key);
        return val;
      },
      set: function() {
        trigger(val, key);
      },
    });
    if (typeof val === "object") {
      defineReactive(val);
    }
  }}function trigger(val, key) {
  console.log("sue set", val, key);}function track(val, key) {
  console.log("sue set", val, key);}const data = {
  name:'better',
  firends:['1','2']}defineReactive(data)console.log(data.name)console.log(data.firends[1])console.log(data.firends[0])console.log(Object.prototype.toString.call(data))

この関数

defineReactve

は、Object.defineProperty をカプセル化するために使用されます。関数名から、この関数は応答データを定義するためのものであることがわかります。カプセル化後は、データ、キー、および val を渡すだけです。 track 関数は、キーがデータから読み取られるたびにトリガーされます。データはデータのキーに設定されます。関数内のトリガー関数triggers
配列の応答性

Arrayプロトタイプのメソッドを通じて配列の内容を変更し、 getter と setter はトリガーされません

整理した結果、Array プロトタイプで実行できることがわかりました

配列自体の内容を変更するメソッドはそれぞれ 7 つあります
Push pop shift unshift splice sort reverse vue2これらの 7 つのメソッドを書き換えます 実装方法: Array.propertype に基づいて arrayMethods オブジェクトをプロトタイプとして作成し、
Object.setPropertypeOf(o, arryMethods)
o の __proto__ を arrayMethods にポイントします

依存関係を収集する方法Vue2&vue3データ対応原理分析と手動実装(詳細例)

Use

<template><p>{{name}}</p></template>

このテンプレートで使用されるデータ

name

、データを観察する必要がありますデータのプロパティが変更されたときに、それが使用される場所に通知できます。

これが、最初に依存関係を収集する必要がある理由です。つまり、データ名で Collect it を使用し、次にデータが変更されたときに、以前に収集した依存関係ループをトリガーします。要約すると、getter で依存関係を収集し、setter で依存関係をトリガーします。Use proxy

Proxy オブジェクトは、オブジェクトのプロキシを作成するために使用されます。これにより、基本的な操作 (属性の検索、代入、列挙、関数の非アクティブ化など) のインターセプトと定義が実現されます。

##Proxy

でラップされるターゲット オブジェクト (ネイティブ配列、関数、または別のプロキシなど、任意のタイプのオブジェクトにすることができます)。
  • handler

  • 通常、属性として関数を持つオブジェクト。各属性の関数は実行時にそれぞれ定義されます。 . さまざまな操作中の p

    の動作。
  • リフレクトは、JavaScript 操作をインターセプトするメソッドを提供する組み込みオブジェクトです。これらのメソッドは、プロパティに値を割り当てるプロキシ ハンドラー
  • ##Reflect.set 関数と同じです。ブール値を返し、更新が成功した場合は true を返します。

    Reflect.get は、target[name]
  • ハイジャックの実装方法

    と同様に、オブジェクトの特定の属性の値を取得します。

    const p = new Proxy(target, handler)
    コード内ディナー オブジェクトはハンドラーにプロキシされます。すべてのプロパティを監視するには、
    defineProperty
defineProperty

のプロパティ間の違いを調べる必要があります。

プロキシを使用すると、オブジェクトのすべてのプロパティを処理できます。 プロキシ

プロキシを使用して、シミュレートされた応答を実装します。

const dinner = {
  meal:'111'}const handler = {
  get(target, prop) {
    console.log('get...', prop)
    return Reflect.get(...arguments)
  },
  set(target, key, value) {
    console.log('get...', prop)
    console.log('set',key,value)
    return Reflect.set(...arguments)
  }}const proxy = new Proxy(dinner, handler)console.log(proxy.meal)console.log(proxy.meal)

実行後に自動的に印刷します。

考察: get で再帰のみを使用するのはなぜで、 set が使用されない場合はどうなるでしょうか?

代入には get first も必要です

簡単な要約:

vue2 (応答性が浅い)

Vue2&vue3データ対応原理分析と手動実装(詳細例)

データをトラバースし、defineProperty を使用してすべてのプロパティをインターセプトします

ユーザーがビューを操作すると、設定されたインターセプターがトリガーされます

set は最初に現在のデータを変更し、次に wartch に通知し、watch にビューの更新を通知させます

ビューを再描画し、get again から対応するデータを取得します
  1. ##vue3 (深い応答性):
  • プロキシにはプロキシを使用; 属性の読み取りと書き込み、属性の追加、
  • リフレクションには Reflect を使用します。プロキシ オブジェクトの対応するプロパティに対して特定の操作を動的に実行します。
  1. リフレクション オブジェクト ( Reflect) のプロキシ オブジェクト (プロキシ) は、応答性を実現するために相互に連携する必要があります
  • 2 つの違いは、

    プロキシはオブジェクト全体をハイジャックできるのに対し、オブジェクトはオブジェクトです。 defineProperty はオブジェクトのプロパティをハイジャックすることしかできません。前者はプロパティに対応する値のプロキシを再帰的に返すことで応答性を実現できますが、後者は各属性を深く走査する必要があり、後者は配列操作には非常に不向きです。
  • プログラミング関連の知識について詳しくは、

    プログラミング入門

    をご覧ください。 !

以上がVue2&vue3データ対応原理分析と手動実装(詳細例)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はcsdn.netで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。