検索
ホームページウェブフロントエンドVue.jsVue3 応答システムで計算されたシステムを実装する方法

まず最初に、簡単に復習しましょう:

レスポンシブ システムの中核は、WeakMap --- Map --- Set データ構造です。

Vue3 応答システムで計算されたシステムを実装する方法

#WeakMap のキーは元のオブジェクトで、値は応答する Map です。このように、オブジェクトが破棄されると、対応するマップも破棄されます。

Map のキーはオブジェクトの各属性であり、値はこのオブジェクトの属性に依存する一連の効果関数です。次に、Proxy プロキシ オブジェクトの get メソッドを使用して、オブジェクトのプロパティに依存するエフェクト関数をキーに対応する Set に収集します。オブジェクトのプロパティを変更するときに、オブジェクトの set メソッドをプロキシし、キーのすべてのエフェクト関数を呼び出すことも必要です。

前回の記事では、このアイデアに基づいて比較的完全なレスポンシブ システムを実装しました。その後、今日もコンピューティングの実装を続けます。

computed の実装

まず、前のコードを再構築し、依存関係の収集と依存関係関数のトリガーの実行をトラック関数とトリガー関数に分離します。

Vue3 応答システムで計算されたシステムを実装する方法

ロジックは依然として対応するセットにエフェクトを追加し、対応するセット内でエフェクト関数の実行をトリガーするものですが、抽象化するとより明確になります。

次に、computed の実装を続けます。

computed の使用法はおおよそ次のようになります:

const value = computed(() => {
    return obj.a + obj.b;
});

効果を比較します:

effect(() => {
    console.log(obj.a);
});

違いは 1 つだけです戻り値が増えます。

したがって、次のような効果に基づいて計算を実装します:

function computed(fn) {
    const value = effect(fn);
   return value
}

もちろん、現在の効果には戻り値がないため、それを追加する必要があります。

Vue3 応答システムで計算されたシステムを実装する方法

戻り値を記録し、エフェクト関数の以前の実行に基づいてそれを返すだけです。この変換も非常に簡単です。

Now computed は計算値を返すことができます:

Vue3 応答システムで計算されたシステムを実装する方法

ただし、データが渡され、すべてのエフェクトが実行されます。エフェクトはここにあります。 like computed は毎回再実行する必要はなく、データが変更された後にのみ実行する必要があります。

そこで、エフェクトがすぐに実行されないように制御するための遅延オプションを追加しますが、関数を返してユーザーが自分で実行できるようにします。

Vue3 応答システムで計算されたシステムを実装する方法

次に、計算結果でエフェクトを使用する場合、エフェクト関数が実行されずに返されるように、遅延オプションを追加します。

計算結果でオブジェクトを作成し、値の取得がトリガーされたときにこの関数を呼び出して最新の値を取得します:

Vue3 応答システムで計算されたシステムを実装する方法

テストしてみましょう:

Vue3 応答システムで計算されたシステムを実装する方法

計算された戻り値の value 属性が計算された値を取得できるようになり、obj.a が変更されたことがわかります。その後、計算関数が再実行され、再度値を取得すると新しい値が得られます。

もう 1 つの計算を実行します。これは、obj.a が変更されるとすべてのエフェクト関数が実行されるためです。

Vue3 応答システムで計算されたシステムを実装する方法

この例では、つまり、データが変更されるたびに、計算関数が再実行されて最新の値が計算されます。

これは必須ではありませんが、エフェクト機能を実行するかどうかも制御できるようにする必要があります。したがって、それにスケジューリング関数を追加する必要があります。

Vue3 応答システムで計算されたシステムを実装する方法

は、スケジューラー コールバック関数の受け渡しをサポートし、スケジューラーがある場合はエフェクトの実行時に実行できます。 、それを渡します。ユーザーが自分でスケジュールできるようにします。そうでない場合は、エフェクト関数が実行されます。

この方法で、ユーザーはエフェクト関数の実行を制御できます:

Vue3 応答システムで計算されたシステムを実装する方法

その後、コードをもう一度試してください:

Vue3 応答システムで計算されたシステムを実装する方法

#ご覧のとおり、obj.a が変更された後、エフェクト関数は再計算のために実行されませんでした。これは、独自にスケジュールするためにシェデュラーを追加したためです。これにより、データ変更直後に計算された関数を実行する必要がなくなり、実行を自分で制御できるようになります。

ここで別の問題が発生します。res.value にアクセスするたびに、値を計算する必要があります:

Vue3 応答システムで計算されたシステムを実装する方法

能不能加个缓存呢?只有数据变了才需要计算,否则直接拿之前计算的值。

当然是可以的,加个标记就行:

Vue3 応答システムで計算されたシステムを実装する方法

scheduler 被调用的时候就说明数据变了,这时候 dirty 设置为 true,然后取 value 的时候就重新计算,之后再改为 false,下次取 value 就直接拿计算好的值了。

我们测试下:

Vue3 応答システムで計算されたシステムを実装する方法

我们访问 computed 值的 value 属性时,第一次会重新计算,后面就直接拿计算好的值了。

修改它依赖的数据后,再次访问 value 属性会再次重新计算,然后后面再访问就又会直接拿计算好的值了。

至此,我们完成了 computed 的功能。

但现在的 computed 实现还有一个问题,比如这样一段代码:

let res = computed(() => {
    return obj.a + obj.b;
});
effect(() => {
    console.log(res.value);
});

我们在一个 effect 函数里用到了 computed 值,按理说 obj.a 变了,那 computed 的值也会变,应该触发所有的 effect 函数。

但实际上并没有:

Vue3 応答システムで計算されたシステムを実装する方法

这是为什么呢?

这是因为返回的 computed 值并不是一个响应式的对象,需要把它变为响应式的,也就是 get 的时候 track 收集依赖,set 的时候触发依赖的执行:

Vue3 応答システムで計算されたシステムを実装する方法

我们再试一下:

Vue3 応答システムで計算されたシステムを実装する方法

现在 computed 值变了就能触发依赖它的 effect 了。至此,我们的 computed 就很完善了。

完整代码如下:

const data = {
    a: 1,
    b: 2
}
let activeEffect
const effectStack = [];
function effect(fn, options = {}) {
  const effectFn = () => {
      cleanup(effectFn)
      activeEffect = effectFn
      effectStack.push(effectFn);
      const res = fn()
      effectStack.pop()
      activeEffect = effectStack[effectStack.length - 1]
      return res
  }
  effectFn.deps = []
  effectFn.options = options;
  if (!options.lazy) {
    effectFn()
  }
  return effectFn
}
function computed(fn) {
    let value
    let dirty = true
    const effectFn = effect(fn, {
        lazy: true,
        scheduler(fn) {
            if(!dirty) {
                dirty = true
                trigger(obj, 'value');
            }
        }
    });
    const obj = {
        get value() {
            if (dirty) {
                value = effectFn()
                dirty = false
            }
            track(obj, 'value');
            console.log(obj);
            return value
        }
    }
    return obj
}
function cleanup(effectFn) {
    for (let i = 0; i < effectFn.deps.length; i++) {
        const deps = effectFn.deps[i]
        deps.delete(effectFn)
    }
    effectFn.deps.length = 0
}
const reactiveMap = new WeakMap()
const obj = new Proxy(data, {
    get(targetObj, key) {
        track(targetObj, key);

        return targetObj[key]
   },
   set(targetObj, key, newVal) {
        targetObj[key] = newVal

        trigger(targetObj, key)
    }
})
function track(targetObj, key) {
    let depsMap = reactiveMap.get(targetObj)
    if (!depsMap) {
    reactiveMap.set(targetObj, (depsMap = new Map()))
    }
    let deps = depsMap.get(key)
    if (!deps) {
    depsMap.set(key, (deps = new Set()))
    }
    deps.add(activeEffect)
    activeEffect.deps.push(deps);
}
function trigger(targetObj, key) {
    const depsMap = reactiveMap.get(targetObj)
    if (!depsMap) return
    const effects = depsMap.get(key)
    const effectsToRun = new Set(effects)
    effectsToRun.forEach(effectFn => {
        if(effectFn.options.scheduler) {
            effectFn.options.scheduler(effectFn)
        } else {
            effectFn()
        }
    })
}

以上がVue3 応答システムで計算されたシステムを実装する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明
この記事は亿速云で複製されています。侵害がある場合は、admin@php.cn までご連絡ください。
Netflixのフロントエンドの反応、Vue、および未来Netflixのフロントエンドの反応、Vue、および未来Apr 12, 2025 am 12:12 AM

Netflixは、主にReactをフロントエンドフレームワークとして使用し、特定の機能のためにVUEによって補足されます。 1)Reactのコンポーネント化と仮想DOMは、Netflixアプリケーションのパフォーマンスと開発効率を向上させます。 2)VueはNetflixの内部ツールと小規模プロジェクトで使用されており、その柔軟性と使いやすさが重要です。

フロントエンドのvue.js:実際のアプリケーションと例フロントエンドのvue.js:実際のアプリケーションと例Apr 11, 2025 am 12:12 AM

Vue.jsは、複雑なユーザーインターフェイスを構築するのに適した進歩的なJavaScriptフレームワークです。 1)そのコア概念には、レスポンシブデータ、コンポーネント、仮想DOMが含まれます。 2)実際のアプリケーションでは、TODOアプリケーションを構築し、Vuerouterを統合することで実証できます。 3)デバッグするときは、vuedevtools and Console.logを使用することをお勧めします。 4)パフォーマンスの最適化は、V-IF/V-Show、リストレンダリング最適化、コンポーネントの非同期負荷などを通じて達成できます。

Vue.jsとReact:重要な違​​いを理解するVue.jsとReact:重要な違​​いを理解するApr 10, 2025 am 09:26 AM

Vue.JSは中小企業から中規模のプロジェクトに適していますが、Reactは大規模で複雑なアプリケーションにより適しています。 1。VUE.JSのレスポンシブシステムは、依存関係追跡を介してDOMを自動的に更新し、データの変更を簡単に管理できるようにします。 2.反応は一方向のデータフローを採​​用し、データは親コンポーネントから子コンポーネントに流れ、明確なデータフローと簡単な抽出構造を提供します。

Vue.js vs. React:プロジェクト固有の考慮事項Vue.js vs. React:プロジェクト固有の考慮事項Apr 09, 2025 am 12:01 AM

VUE.JSは、中小規模のプロジェクトや迅速な反復に適していますが、Reactは大規模で複雑なアプリケーションに適しています。 1)Vue.jsは使いやすく、チームが不十分な状況やプロジェクトスケールが小さい状況に適しています。 2)Reactにはより豊富なエコシステムがあり、高性能で複雑な機能的ニーズを持つプロジェクトに適しています。

Vueにタグをジャンプする方法Vueにタグをジャンプする方法Apr 08, 2025 am 09:24 AM

VUEでタグのジャンプを実装する方法には、HTMLテンプレートでAタグを使用してHREF属性を指定する方法が含まれます。 VUEルーティングのルーターリンクコンポーネントを使用します。 JavaScriptでこれを使用します。$ router.push()メソッド。パラメーターはクエリパラメーターに渡すことができ、ルートは動的ジャンプのルーターオプションで構成されています。

VUEのコンポーネントジャンプを実装する方法VUEのコンポーネントジャンプを実装する方法Apr 08, 2025 am 09:21 AM

VUEでコンポーネントジャンプを実装するための次の方法があります。Router-Linkと&lt; router-view&gt;を使用してください。ハイパーリンクジャンプを実行し、ターゲットパスとして属性を指定するコンポーネント。 &lt; router-view&gt;を使用してください現在ルーティングされているレンダリングされているコンポーネントを表示するコンポーネント。プログラマティックナビゲーションには、router.push()およびrouter.replace()メソッドを使用します。前者は歴史を保存し、後者は記録を残さずに現在のルートに取って代わります。

VueのDivにジャンプする方法VueのDivにジャンプする方法Apr 08, 2025 am 09:18 AM

VUEにDIV要素をジャンプするには、VUEルーターを使用してルーターリンクコンポーネントを追加するには、2つの方法があります。 @clickイベントリスナーを追加して、これを呼び出します。$ router.push()メソッドをジャンプします。

ジャンプVUEによって価値を転送する方法ジャンプVUEによって価値を転送する方法Apr 08, 2025 am 09:15 AM

VUEにデータを渡す主な方法は2つあります。PROPS:一方向データバインディング、親コンポーネントから子コンポーネントにデータを渡します。イベント:イベントとカスタムイベントを使用してコンポーネント間でデータを渡します。

See all articles

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

MinGW - Minimalist GNU for Windows

MinGW - Minimalist GNU for Windows

このプロジェクトは osdn.net/projects/mingw に移行中です。引き続きそこでフォローしていただけます。 MinGW: GNU Compiler Collection (GCC) のネイティブ Windows ポートであり、ネイティブ Windows アプリケーションを構築するための自由に配布可能なインポート ライブラリとヘッダー ファイルであり、C99 機能をサポートする MSVC ランタイムの拡張機能が含まれています。すべての MinGW ソフトウェアは 64 ビット Windows プラットフォームで実行できます。

SAP NetWeaver Server Adapter for Eclipse

SAP NetWeaver Server Adapter for Eclipse

Eclipse を SAP NetWeaver アプリケーション サーバーと統合します。

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

Dreamweaver Mac版

Dreamweaver Mac版

ビジュアル Web 開発ツール

SublimeText3 Linux 新バージョン

SublimeText3 Linux 新バージョン

SublimeText3 Linux 最新バージョン