目次
前回の記事で、reactive が実際にはプロキシ オブジェクトであることも紹介しました。
vue3 では、ref は get と set によって実装されます。
データ プロキシは完成しましたが、データが変更された後、双方向バインディングを実装するようにコンポーネントに通知するにはどうすればよいでしょうか?
データ プロキシは複雑ではなく、プロキシに基づいており、いくつかの境界処理が追加されています。応答性を実現するには、依存関係の収集と依存関係のトリガーの実装を追加する必要があります。
ホームページ ウェブフロントエンド Vue.js Vue のレスポンシブ データ処理方法の詳細な分析

Vue のレスポンシブ データ処理方法の詳細な分析

Mar 28, 2023 pm 07:14 PM
フロントエンド vue.js

この記事は、vue を学習し、vue がレスポンシブ データをどのように処理するかについて説明するのに役立ちます。お役に立てれば幸いです!

Vue のレスポンシブ データ処理方法の詳細な分析

vue のレスポンシブ データについては多くの疑問があるかもしれません。

たとえば、なぜ代わりにプロキシを使用する必要があるのですか?

たとえば、なぜ 2 つの API (reactive と ref) があるのですか?

たとえば、vue はどのように応答性を実装するのでしょうか?

実際、これらに対する答えはソース コードの中にあります。

最初の記事「vue3 のアップグレードとは」では、プロキシを使用する利点と Object.defineProperty の欠点についても触れました。しかし今日は角度を変えて、chatGPT にこの質問に答えてもらいたいと思います。 [関連する推奨事項: vuejs ビデオ チュートリアル Web フロントエンド開発 ]

そうですね、私が要約したものよりも優れていると思います。

Vue のレスポンシブ データ処理方法の詳細な分析

# それでは、次の質問に進みます。

Vue のレスポンシブ データ処理方法の詳細な分析

この答えはより正式なものに感じられ、私が望む答えは得られません。

その理由は実際には非常に簡単で、プロキシ メソッドは値の型をプロキシできず、オブジェクトのみをプロキシできるからです。したがって、値型データを処理するには追加のメソッドが必要です。

もちろん、1 つの ref で世界を征服することもできます。vue のソースコードに互換性があれば、自動的に変換されます。

これを理解した上で、今日のを見てみましょう。 ハイライトは、vue3 のソース コードを模倣し、応答性の高いシステムを実装することです。

関連するコードをクリックして表示し、記事のタイトルに従ってさまざまなブランチを選択できます。 reactive の実装

前回の記事で、reactive が実際にはプロキシ オブジェクトであることも紹介しました。

プロキシを使用して、単純なプロキシ関数をリアクティブに実装できます。

      function reactive(target) {        const isObject = (val) =>  val !== null && typeof val === 'object'

        if (!isObject(target)) {          console.warn(`数据必须是对象: ${String(target)}`)          return target
        }        const proxy = new Proxy(target, {          get: (target, key, receiver) => {            console.log('get', key)            const res = Reflect.get(target, key, receiver)            // track(target, key)
            // 这句很关键,不然嵌套数据,里面的不会响应
            if (isObject(res)) {              return reactive(res)
            }            return res
          },          set: (target, key, value, receiver) => {            console.log('set', key, value)            const result = Reflect.set(target, key, value, receiver)            // trigger(target, key, value)
            return result
          },          deleteProperty: () => {            const result = Reflect.deleteProperty(target, key)            return result
          }
        })        return proxy
      }      const person = reactive({        name: '',        age: 18,        like: ['apple']
      })

      person.name  = 'vue test'复制代码
ログイン後にコピー

注: Reflect

Reflect.get(target, key) は、target[key] に直接アクセスすることとは少し異なります。

プロキシ オブジェクト内で this が指す get、set などがある場合、これをリダイレクトできます。

例:

        const person = new Proxy({            name: "vue test",            age: 18,            get info() {                return 'name is :' + this.name + ' age is:' + this.age
            }
        }, {            get: (target, key, receiver) => {                console.log('get', key)                // return target[key]
                return Reflect.get(target, key, receiver)
            }
        })        console.log(person.info)复制代码
ログイン後にコピー

Reflect を使用すると、名前と年齢にアクセスするときにトリガーできます。

Vue のレスポンシブ データ処理方法の詳細な分析ターゲットに変更した後は、情報内で 1 回だけトリガーされます。

return target[key]复制代码
ログイン後にコピー

Vue のレスポンシブ データ処理方法の詳細な分析ref の実装

vue3 では、ref は get と set によって実装されます。

上記と同様に、最初に関数を宣言し、次に get および set を通じてデータにアクセスします。

      function ref(value) {        return new RefImpl(value)
      }      class RefImpl {        constructor(value) {          // 如果值是对象,则用reactive处理
          this._value = isObject(value) ? reactive(value) : value          // 记录一下初始值
          this._rawValue = value
        }        get value() {          // trackRefValue(this)
          return this._value
        }        set value(newVal) {          if (!Object.is(newVal, this._rawValue)) {            // 更新原始数据
            this._rawValue = newVal            // 更新 .value 的值
            this._value = isObject(newVal) ? reactive(newVal) : value            // triggerRefValue(this)
          }
        }
      }复制代码
ログイン後にコピー

ソース コードでは、get/set が value を通じて設定されるため、.value で ref を使用する必要がある理由も非常に直感的に説明されています。

依存関係の収集とトリガーを追加する

データ プロキシは完成しましたが、データが変更された後、双方向バインディングを実装するようにコンポーネントに通知するにはどうすればよいでしょうか?

答えは、コレクションとトリガーに依存することです。つまり、get がトリガーされると、get をトリガーする条件 [関数] を保存します。set がトリガーされると、それを再実行して条件 [関数] をトリガーします。 ]. ]それだけでは十分ではありませんか?

もう一度コードを見て、トラック収集メソッドとターゲット トリガー メソッドを追加します。 (つまり、上記のコード スニペットでコメントアウトされた 2 行のコード)

さらに、トリガー関数を管理するためにエフェクト関数も必要です。

      let activeEffect = null
      const targetMap = new WeakMap()      // 依赖收集/触发
      function track(target, key) {        let depsMap = targetMap.get(target)        if (!depsMap) {
          targetMap.set(target, (depsMap = new Map()))
        }        let dep = depsMap.get(key)        if (!dep) {
          dep = new Set()
        }
        dep.add(activeEffect)
        depsMap.set(key, dep)
      }      function trigger(target, key, value) {        const depsMap = targetMap.get(target)        if (!depsMap) {          return
        }        const deps = depsMap.get(key)        if (!deps) {          return
        }

        deps.forEach(effectFn => {          if (effectFn.scheduler) {
            effectFn.scheduler()
          } else {            effectFn()
          }
        })
      }      function effect(fn,options = {}) {        const effectFn = () => {          try {
            activeEffect = effectFn            return fn()
          } catch (error) {
            activeEffect = null
          }
        }        if (!options.lazy) {          effectFn()
        }
        effectFn.scheduler = options.scheduler
        return effectFn
      }      const person = reactive({        name: "hello world"
      })      effect(() => {        console.log('effect person', person.name)
      })      setTimeout(() => {
        person.name = 'setTimeout world'
      }, 2000)复制代码
ログイン後にコピー

activeEffect は、トリガー条件関数を保存するために使用されます。

targetMap は依存関係辞書を格納するために使用されます。形式は次のとおりです

{
    target: {
        key: []
    }
}复制代码
ログイン後にコピー

出力結果は hello world です。2 秒後に依存関係関数が再実行され、setTimeout world が出力されます

Vue のレスポンシブ データ処理方法の詳細な分析概要

データ プロキシは複雑ではなく、プロキシに基づいており、いくつかの境界処理が追加されています。応答性を実現するには、依存関係の収集と依存関係のトリガーの実装を追加する必要があります。

effect は非常に重要な関数であり、useEffect や watch など多くの API がこの関数をベースにして開発されています。コンポーネントの更新も後述するエフェクト機能に基づいて行われます。

効果がわからない場合は、実行順序を整理してください。

  • 1. エフェクト関数を呼び出し、パラメーター fn
  • 2 を渡します。effectFn 関数を宣言して実行し、関数を activeEffect# として保存します。
  • ##3. fn を実行して person.name を読み取ります
  • 4. プロキシの get proxy を使用します
  • 5. 依存関係を収集し、activeEffect で保存した関数をグローバル マップに保存します
  • #6. このとき、エフェクト関数は実行され、データの更新を待機します
  • #7.2秒後、プロキシの設定プロキシに移動
  • 8. グローバルマップに保存した関数を実行し、エフェクト関数を再実行し、再び手順1に戻ります。
  • クリックして関連コード
を表示し、lesson3 ブランチを選択できます。

記事に関連するコードは vue/examples で参照でき、vue の模倣実装バージョンは package/reactivity で参照できます。

(学習ビデオ共有:

vuejs 入門チュートリアル

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

以上がVue のレスポンシブ データ処理方法の詳細な分析の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホット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ヘンタイを無料で生成します。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

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

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

Nodeのメモリ制御に関する記事 Nodeのメモリ制御に関する記事 Apr 26, 2023 pm 05:37 PM

ノンブロッキングおよびイベント駆動に基づいて構築されたノード サービスには、メモリ消費量が少ないという利点があり、大量のネットワーク リクエストの処理に非常に適しています。大量のリクエストを前提として、「メモリ制御」に関する問題を考慮する必要があります。 1. V8 のガベージ コレクション メカニズムとメモリ制限 Js はガベージ コレクション マシンによって制御されます

PHP と Vue: フロントエンド開発ツールの完璧な組み合わせ PHP と Vue: フロントエンド開発ツールの完璧な組み合わせ Mar 16, 2024 pm 12:09 PM

PHP と Vue: フロントエンド開発ツールの完璧な組み合わせ 今日のインターネットの急速な発展の時代において、フロントエンド開発はますます重要になっています。 Web サイトやアプリケーションのエクスペリエンスに対するユーザーの要求がますます高まっているため、フロントエンド開発者は、より効率的で柔軟なツールを使用して、応答性の高いインタラクティブなインターフェイスを作成する必要があります。フロントエンド開発の分野における 2 つの重要なテクノロジーである PHP と Vue.js は、組み合わせることで完璧なツールと見なされます。この記事では、PHP と Vue の組み合わせと、読者がこれら 2 つをよりよく理解し、適用できるようにするための詳細なコード例について説明します。

クロスドメインの問題を解決するにはどうすればよいですか?一般的なソリューションの簡単な分析 クロスドメインの問題を解決するにはどうすればよいですか?一般的なソリューションの簡単な分析 Apr 25, 2023 pm 07:57 PM

クロスドメインは開発においてよく遭遇するシナリオであり、インタビューでもよく議論される問題でもあります。一般的なクロスドメイン ソリューションとその背後にある原則を習得すると、開発効率が向上するだけでなく、面接でのパフォーマンスも向上します。

フロントエンド開発に Go 言語を使用するにはどうすればよいですか? フロントエンド開発に Go 言語を使用するにはどうすればよいですか? Jun 10, 2023 pm 05:00 PM

インターネット技術の発展に伴い、フロントエンド開発の重要性がますます高まっています。特にモバイル デバイスの人気により、効率的で安定しており、安全で保守が容易なフロントエンド開発テクノロジーが必要です。 Go 言語は、急速に発展しているプログラミング言語として、ますます多くの開発者によって使用されています。では、フロントエンド開発に Go 言語を使用することは可能でしょうか?次に、この記事ではフロントエンド開発にGo言語を使用する方法を詳しく説明します。まずはフロントエンド開発にGo言語が使われる理由を見てみましょう。多くの人は Go 言語は

フロントエンドの面接官からよく聞かれる質問 フロントエンドの面接官からよく聞かれる質問 Mar 19, 2024 pm 02:24 PM

フロントエンド開発のインタビューでは、HTML/CSS の基本、JavaScript の基本、フレームワークとライブラリ、プロジェクトの経験、アルゴリズムとデータ構造、パフォーマンスの最適化、クロスドメイン リクエスト、フロントエンド エンジニアリング、デザインパターン、新しいテクノロジーとトレンド。面接官の質問は、候補者の技術スキル、プロジェクトの経験、業界のトレンドの理解を評価するように設計されています。したがって、候補者はこれらの分野で自分の能力と専門知識を証明するために十分な準備をしておく必要があります。

Django はフロントエンドですか、バックエンドですか?それをチェックしてください! Django はフロントエンドですか、バックエンドですか?それをチェックしてください! Jan 19, 2024 am 08:37 AM

Django は、迅速な開発とクリーンなメソッドを重視した Python で書かれた Web アプリケーション フレームワークです。 Django は Web フレームワークですが、Django がフロントエンドなのかバックエンドなのかという質問に答えるには、フロントエンドとバックエンドの概念を深く理解する必要があります。フロントエンドはユーザーが直接対話するインターフェイスを指し、バックエンドはサーバー側プログラムを指し、HTTP プロトコルを通じてデータと対話します。フロントエンドとバックエンドが分離されている場合、フロントエンドとバックエンドのプログラムをそれぞれ独立して開発して、ビジネス ロジックとインタラクティブ効果、およびデータ交換を実装できます。

golang はフロントエンドとして使用できますか? golang はフロントエンドとして使用できますか? Jun 06, 2023 am 09:19 AM

Golang はフロントエンドとして使用できます。Golang は、フロントエンド アプリケーションなど、さまざまなタイプのアプリケーションの開発に使用できる非常に多用途なプログラミング言語です。Golang を使用してフロントエンドを作成することで、 JavaScript などの言語によって引き起こされる一連の問題、たとえば、型安全性の低さ、パフォーマンスの低下、コードの保守の困難などの問題です。

C# 開発経験の共有: フロントエンドとバックエンドの共同開発スキル C# 開発経験の共有: フロントエンドとバックエンドの共同開発スキル Nov 23, 2023 am 10:13 AM

C# 開発者としての私たちの開発作業には、通常、フロントエンドとバックエンドの開発が含まれますが、テクノロジーが発展し、プロジェクトが複雑になるにつれて、フロントエンドとバックエンドの共同開発はますます重要かつ複雑になってきています。この記事では、C# 開発者が開発作業をより効率的に完了できるようにする、フロントエンドとバックエンドの共同開発テクニックをいくつか紹介します。インターフェイスの仕様を決定した後、フロントエンドとバックエンドの共同開発は API インターフェイスの相互作用から切り離せません。フロントエンドとバックエンドの共同開発をスムーズに進めるためには、適切なインターフェース仕様を定義することが最も重要です。インターフェイスの仕様にはインターフェイスの名前が含まれます

See all articles