検索
ホームページウェブフロントエンドVue.jsVue2実装APIの原理を解析する

Vue2実装APIの原理を解析する

Jan 13, 2023 am 08:30 AM
フロントエンドvue.js

Vue2実装APIの原理を解析する

Vue3 のリリース以来、composition API という言葉が、Vue を作成する学生の目に入るようになりました。 composition API は以前の options API よりもはるかに優れているということは誰もが聞いたことがあると思います。@vue/composition-api## のリリースにより、 # プラグイン、 Vue2 学生も参加できます。次に、主にレスポンシブ refreactive を使用して、詳細な分析を行います。このプラグインがこの機能をどのように実装するか。

使い方
// 入口文件引入并注册
import Vue from 'vue'
import VueCompositionAPI from '@vue/composition-api'

Vue.use(VueCompositionAPI)
// vue文件使用
import { defineComponent, ref, reactive } from '@vue/composition-api'

export default defineComponent({
  setup () {
     const foo = ref('foo');
     const obj = reactive({ bar: 'bar' });
     
     return {
        foo,
        obj
     }
  }
})

どうですか?読んだ後、

vue3 とまったく同じように感じますか?次のように思うかもしれません:

  • これは

    vue2 です。ああ、以前の datamethods にも変数とメソッドが含まれています。どうすればよいですか? setup# と同じように実行します。 ## 戻り値はマージされます。 [関連する推奨事項: vuejs ビデオ チュートリアル Web フロントエンド開発 ]

  • vue2

    は、 data 内のデータは応答的に処理されますか? refreactive はどのように行うのでしょうか?

  • vue2

    レスポンシブ データによって定義された制約 (元のオブジェクトに割り当てられていない属性の追加、配列の添字の変更など)、ref# を使用します。 ## 代わりに reactive でよろしいでしょうか?

    もちろん、このプラグインは非常に多くの
  • API
を提供し、

Vue3## のほとんどをカバーしているため、まだ多くの疑問があります。 # has, here 主にこれらの質問からそれがどのように行われるかを分析してみましょう。 原理分析

Vue のプラグイン システムのおかげで、

@vue/composition-api

は次のようになります vue-router および vuex も、公式に提供されるプラグインを通じて挿入されます。 <pre class='brush:php;toolbar:false;'>// 这里只贴跟本章要讲的相关代码 funciton mixin (Vue) { Vue.mixin({ beforeCreate: functionApiInit } } function install (Vue) { mixin(Vue); } export const Plugin = { install: (Vue: VueConstructor) =&gt; install(Vue), }</pre>Vue プラグインは、

install

メソッドを外部に公開します。use が呼び出されると、このメソッドが呼び出され、 Vue コンストラクターはパラメーターとして渡され、対応するフックでミックスするときに関数を処理するために Vue.mixin が呼び出されます。 次のステップは、functionApiInit が何をするのかを確認することです。

function functionApiInit(this: ComponentInstance) {
  const vm = this
  const $options = vm.$options
  const { setup, render } = $options
  
  // render 相关
  
  
  const { data } = $options
  
  $options.data = function wrappedData() {
    initSetup(vm, vm.$props)
    return isFunction(data)
     ? (
        data as (this: ComponentInstance, x: ComponentInstance) => object
      ).call(vm, vm)
     : data || {}
  }

なぜなら、Vue

beforeCreated

にあるからです。 created ライフサイクル中、データは initState によって処理されます。data を処理するとき、$options.data が呼び出され、定義されたデータを取得します。 data. , したがって、関数はここで再ラップされます。これが、beforeCreate フック インジェクションが選択される理由の 1 つです。フック インジェクションは、関数が呼び出される前にラップする必要があります。 次に、initSetup <pre class='brush:php;toolbar:false;'>function initSetup(vm: ComponentInstance, props: Record&lt;any, any&gt; = {}) { const setup = vm.$options.setup! const ctx = createSetupContext(vm) const instance = toVue3ComponentInstance(vm) instance.setupContext = ctx def(props, &amp;#39;__ob__&amp;#39;, createObserver()) resolveScopedSlots(vm, ctx.slots) let binding: ReturnType&lt;SetupFunction&lt;Data, Data&gt;&gt; | undefined | null activateCurrentInstance(instance, () =&gt; { binding = setup(props, ctx) }) // setup返回是函数的情况 需要重写render函数 const bindingObj = binding Object.keys(bindingObj).forEach((name) =&gt; { let bindingValue: any = bindingObj[name] // 数据处理 asVmProperty(vm, name, bindingValue) }) return } }</pre>この関数は比較的長い関数なので、今回説明する本行以外のコードロジックは削除されています。 ctx を実行し、

vm

インスタンスを Vue3 データ型で定義された instance に変換してから、setup を実行します。関数を使用して戻り値を取得し、トラバースします 各プロパティについて、 asVmProperty を呼び出して vm にマウントします もちろん、ここでのマウントはプロパティと値を直接追加することではありませんvm に同期すると、問題が発生します。つまり、この属性に対する後続の変更を vm に同期できません。Vue## の最も一般的なデータ プロキシここでは # が使用されます。

export function asVmProperty(
  vm: ComponentInstance,
  propName: string,
  propValue: Ref<unknown>
) {
  const props = vm.$options.props
  if (!(propName in vm) && !(props && hasOwn(props, propName))) {
    if (isRef(propValue)) {
      proxy(vm, propName, {
        get: () => propValue.value,
        set: (val: unknown) => {
          propValue.value = val
        },
      })
    } else {
      proxy(vm, propName, {
        get: () => {
          if (isReactive(propValue)) {
            ;(propValue as any).__ob__.dep.depend()
          }
          return propValue
        },
        set: (val: any) => {
          propValue = val
        },
      })
    }
}
これを見て、setup で定義した戻り値が template

data、## で使用できる理由が理解できたと思います。 # メソッド など。返されたものは vm にプロキシされているためです。 応答性 (ref reactive

実装)

次に、応答性とその理由について話しましょう refおよび reactive はデータをリアクティブにすることもできます。

ref の実装は、実際には reactive の再カプセル化であり、主に基本型に使用されます。

function ref(raw?: unknown) {
  if (isRef(raw)) {
    return raw
  }

  const value = reactive({ [RefKey]: raw })
  return createRef({
    get: () => value[RefKey] as any,
    set: (v) => ((value[RefKey] as any) = v),
  })
}

reactive はオブジェクトを受け入れる必要があるため、ここでは ref

key

(つまり ) として定数が使用されています。<pre class='brush:php;toolbar:false;'>const value = reactive({ &quot;composition-api.refKey&quot;: row })</pre><pre class='brush:php;toolbar:false;'>export function createRef&lt;T&gt;( options: RefOption&lt;T&gt;, isReadonly = false, isComputed = false ): RefImpl&lt;T&gt; { const r = new RefImpl&lt;T&gt;(options) const sealed = Object.seal(r) if (isReadonly) readonlySet.set(sealed, true) return sealed } export class RefImpl&lt;T&gt; implements Ref&lt;T&gt; { readonly [_refBrand]!: true public value!: T constructor({ get, set }: RefOption&lt;T&gt;) { proxy(this, &amp;#39;value&amp;#39;, { get, set, }) } }</pre><p>通过 <code>new RefImpl 实例,该实例上有一个 value 的属性,对 value 做代理,当取值的时候返回 value[RefKey],赋值的时候赋值给 value[RefKey], 这就是为什么 ref 可以用在基本类型,然后对返回值的 .value 进行操作。调用 object.seal 是把对象密封起来(会让这个对象变的不能添加新属性,且所有已有属性会变的不可配置。属性不可配置的效果就是属性变的不可删除,以及一个数据属性不能被重新定义成为访问器属性,或者反之。但属性的值仍然可以修改。)

我们主要看下 reactive 的实现

export function reactive<T extends object>(obj: T): UnwrapRef<T> {
    const observed = observe(obj)
    setupAccessControl(observed)
    return observed as UnwrapRef<T>
}


export function observe<T>(obj: T): T {
  const Vue = getRegisteredVueOrDefault()
  let observed: T
  if (Vue.observable) {
    observed = Vue.observable(obj)
  } else {
    const vm = defineComponentInstance(Vue, {
      data: {
        $$state: obj,
      },
    })
    observed = vm._data.$$state
  }

  return observed
}

我们通过 ref 或者 reactive 定义的数据,最终还是通过了变成了一个 observed 实例对象,也就是 Vue2 在对 data 进行处理时,会调用 observe 返回的一样,这里在 Vue2.6+observe 函数向外暴露为 Vue.observable,如果是低版本的话,可以通过重新 new 一个 vue 实例,借助 data 也可以返回一个 observed 实例,如上述代码。

因为在 reactive 中定义的数据,就如你在 data 中定义的数据一样,都是在操作返回的 observed ,当你取值的时候,会触发 getter 进行依赖收集,赋值时会调用 setter 去派发更新, 只是定义在 setup 中,结合之前讲到的 setup 部分,比如当我们在 template 中访问一个变量的值时,vm.foo -> proxysetup 里面的 foo -> observedfoo ,完成取值的流程,这会比直接在 data 上多代理了一层,因此整个过程也会有额外的性能开销。

因此使用该 API 也不会让你可以直接规避掉 vue2 响应式数据定义的约束,因为最终还是用 Object.defineProperty 去做对象拦截,插件同样也提供了 set API 让你去操作对象新增属性等操作。

总结

通过上面的了解,相信你一定对于 Vue2 如何使用 composition API 有了一定的了解,因为 API 相当多, 响应式相关的就还有 toRefs、toRef、unref、shallowRef、triggerRef 等等,这里就不一一分析,有兴趣的可以继续看源码的实现。

Vue2 的同学也可以不用羡慕写 Vue3 的同学了,直接引入到项目就可以使用起来,虽然没有 vue3 那么好的体验,但是绝大部分场景还是相同的,使用时注意 README 文档最后的限制章节,里面讲了一些使用限制。

(学习视频分享:vuejs入门教程编程基础视频

以上がVue2実装APIの原理を解析するの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明
この記事は掘金社区で複製されています。侵害がある場合は、admin@php.cn までご連絡ください。
vue.jsとフロントエンドスタック:接続の理解vue.jsとフロントエンドスタック:接続の理解Apr 24, 2025 am 12:19 AM

VUE.JSは、開発効率とユーザーエクスペリエンスを向上させるために、フロントエンドテクノロジースタックと密接に統合されています。 1)建設ツール:Webpackおよびロールアップと統合して、モジュール開発を実現します。 2)国家管理:VUEXと統合して、複雑なアプリケーションステータスを管理します。 3)ルーティング:Vuerouterと統合して、単一ページのアプリケーションルーティングを実現します。 4)CSSプリプロセッサ:SASSをサポートし、スタイル開発効率を改善するために少なくなります。

Netflix:React(またはその他のフレームワーク)の使用の調査Netflix:React(またはその他のフレームワーク)の使用の調査Apr 23, 2025 am 12:02 AM

Netflixは、Reactのコンポーネント設計と仮想DOMメカニズムが複雑なインターフェイスと頻繁な更新を効率的に処理できるため、ユーザーインターフェイスを構築するためにReactを選択しました。 1)コンポーネントベースの設計により、Netflixはインターフェイスを管理可能なウィジェットに分解し、開発効率とコード保守性を向上させることができます。 2)仮想DOMメカニズムは、DOM操作を最小化することにより、Netflixユーザーインターフェイスの滑らかさと高性能を保証します。

vue.jsとフロントエンド:フレームワークに深く飛び込むvue.jsとフロントエンド:フレームワークに深く飛び込むApr 22, 2025 am 12:04 AM

Vue.jsは、使いやすく強力なため、開発者に愛されています。 1)そのレスポンシブデータバインディングシステムは、ビューを自動的に更新します。 2)コンポーネントシステムは、コードの再利用性と保守性を向上させます。 3)コンピューティングプロパティとリスナーは、コードの読みやすさとパフォーマンスを向上させます。 4)Vuedevtoolsの使用とコンソールエラーのチェックは、一般的なデバッグ手法です。 5)パフォーマンスの最適化には、主要な属性、計算された属性、およびキープアライブコンポーネントの使用が含まれます。 6)ベストプラクティスには、クリアコンポーネントの命名、単一ファイルコンポーネントの使用、ライフサイクルフックの合理的な使用が含まれます。

フロントエンドのvue.jsの力:主要な機能と利点フロントエンドのvue.jsの力:主要な機能と利点Apr 21, 2025 am 12:07 AM

Vue.jsは、効率的で保守可能なフロントエンドアプリケーションを構築するのに適した進歩的なJavaScriptフレームワークです。その主な機能には、1。レスポンシブデータバインディング、2。コンポーネント開発、3。仮想DOM。これらの機能を通じて、VUE.JSは開発プロセスを簡素化し、アプリケーションのパフォーマンスと保守性を向上させ、最新のWeb開発で非常に人気を博しています。

Vue.jsはReactよりも優れていますか?Vue.jsはReactよりも優れていますか?Apr 20, 2025 am 12:05 AM

Vue.jsとReactにはそれぞれ独自の利点と欠点があり、選択はプロジェクトの要件とチームの条件に依存します。 1)Vue.jsは、シンプルで使いやすいため、小さなプロジェクトや初心者に適しています。 2)Reactは、その豊富な生態系とコンポーネント設計のため、大規模なプロジェクトと複雑なUIに適しています。

Vue.jsの関数:フロントエンドでのユーザーエクスペリエンスの強化Vue.jsの関数:フロントエンドでのユーザーエクスペリエンスの強化Apr 19, 2025 am 12:13 AM

Vue.jsは複数の機能を介してユーザーエクスペリエンスを改善します。1。レスポンシブシステムは、リアルタイムデータフィードバックを実現します。 2。コンポーネント開発により、コードの再利用性が向上します。 3. Vuerouterはスムーズなナビゲーションを提供します。 4.動的データの結合および遷移アニメーションは、相互作用効果を強化します。 5.エラー処理メカニズムにより、ユーザーのフィードバックが保証されます。 6.パフォーマンスの最適化とベストプラクティスは、アプリケーションのパフォーマンスを改善します。

Vue.js:Web開発におけるその役割を定義しますVue.js:Web開発におけるその役割を定義しますApr 18, 2025 am 12:07 AM

Web開発におけるVue.jsの役割は、開発プロセスを簡素化し、効率を向上させるプログレッシブJavaScriptフレームワークとして機能することです。 1)開発者は、レスポンシブデータのバインディングとコンポーネント開発を通じてビジネスロジックに集中できるようになります。 2)VUE.JSの作業原則は、パフォーマンスを最適化するためにレスポンシブシステムと仮想DOMに依存しています。 3)実際のプロジェクトでは、VUEXを使用してグローバルな状態を管理し、データの応答性を最適化することが一般的な慣行です。

Vue.jsの理解:主にフロントエンドフレームワークVue.jsの理解:主にフロントエンドフレームワークApr 17, 2025 am 12:20 AM

Vue.jsは、2014年にYou YuxiがリリースしたプログレッシブJavaScriptフレームワークで、ユーザーインターフェイスを構築します。その中心的な利点には、次のものが含まれます。1。レスポンシブデータバインディング、データ変更の自動更新ビュー。 2。コンポーネントの開発では、UIは独立した再利用可能なコンポーネントに分割できます。

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衣類リムーバー

Video Face Swap

Video Face Swap

完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

ホットツール

MantisBT

MantisBT

Mantis は、製品の欠陥追跡を支援するために設計された、導入が簡単な Web ベースの欠陥追跡ツールです。 PHP、MySQL、Web サーバーが必要です。デモおよびホスティング サービスをチェックしてください。

EditPlus 中国語クラック版

EditPlus 中国語クラック版

サイズが小さく、構文の強調表示、コード プロンプト機能はサポートされていません

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

強力な PHP 統合開発環境

Safe Exam Browser

Safe Exam Browser

Safe Exam Browser は、オンライン試験を安全に受験するための安全なブラウザ環境です。このソフトウェアは、あらゆるコンピュータを安全なワークステーションに変えます。あらゆるユーティリティへのアクセスを制御し、学生が無許可のリソースを使用するのを防ぎます。

SublimeText3 Mac版

SublimeText3 Mac版

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