国产av日韩一区二区三区精品,成人性爱视频在线观看,国产,欧美,日韩,一区,www.成色av久久成人,2222eeee成人天堂

目錄
如何使用
原理解析
響應(yīng)式( ref  reactive 的實(shí)現(xiàn))
總結(jié)
首頁 web前端 Vue.js 解析Vue2實(shí)現(xiàn)composition API的原理

解析Vue2實(shí)現(xiàn)composition API的原理

Jan 13, 2023 am 08:30 AM
前端 vue.js

解析Vue2實(shí)現(xiàn)composition API的原理

自從 Vue3 發(fā)布之后,composition API 這個(gè)詞走入寫 Vue 同學(xué)的視野之中,相信大家也一直聽到 composition API 比之前的 options API 有多好多強(qiáng),如今由于 @vue/composition-api 插件的發(fā)布,Vue2 的同學(xué)也可以上車咯,接下來我們主要以響應(yīng)式的 refreactive 來深入分析一下,這個(gè)插件是怎么實(shí)現(xiàn)此功能的。

如何使用

// 入口文件引入并注冊(cè)
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 一模一樣,你可能會(huì)想:

  • 這是 vue2 啊,我之前的 data 、methods 里面也有變量和方法,怎么做到跟 setup 返回值打通合并在一起的?!鞠嚓P(guān)推薦:vuejs視頻教程、web前端開發(fā)

  • vue2 不是只有定義在 data 里面的數(shù)據(jù)才會(huì)被處理成響應(yīng)式的嗎? refreactive 是怎么做到的呢?

  • vue2 響應(yīng)式數(shù)據(jù)定義的約束(添加賦值原對(duì)象沒有的屬性,數(shù)組下標(biāo)修改等),改用 refreactive 就沒問題嗎?

當(dāng)然還有很多的疑惑,因?yàn)椴寮峁┑?API 相當(dāng)多,覆蓋了絕大部分 Vue3 所擁有的,這里主要從這幾個(gè)問題來分析一下是如何做到的。

原理解析

得益于 Vue 的插件系統(tǒng),@vue/composition-apivue-router 、vuex 一樣也是通過官方提供的插件式來注入。

// 這里只貼跟本章要講的相關(guān)代碼

funciton mixin (Vue) {
    Vue.mixin({
      beforeCreate: functionApiInit
   }
}

function install (Vue) {
    mixin(Vue);
}

export const Plugin = {
  install: (Vue: VueConstructor) => install(Vue),
}

Vue 插件就是向外面暴露一個(gè) install 的方法,當(dāng)調(diào)用 use 的時(shí)候會(huì)調(diào)用該方法,并把 Vue 構(gòu)造函數(shù)作為參數(shù)傳入,然后調(diào)用 Vue.mixin 混入對(duì)應(yīng)鉤子時(shí)要處理的函數(shù)。

接下來主要看下 functionApiInit 做了什么

function functionApiInit(this: ComponentInstance) {
  const vm = this
  const $options = vm.$options
  const { setup, render } = $options
  
  // render 相關(guān)
  
  
  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 || {}
  }

因?yàn)?VuebeforeCreatedcreated 生命周期之間,會(huì) initState 對(duì)數(shù)據(jù)進(jìn)行處理,其中對(duì) data的處理時(shí)就會(huì)調(diào)用 $options.data拿到定義的數(shù)據(jù),所以這里重新對(duì)該函數(shù)其包裹一層,這也是為什么要選擇 beforeCreate 鉤子注入的一個(gè)原因,必須在該函數(shù)調(diào)用前進(jìn)行包裹。 接下來看 initSetup都做了什么

function initSetup(vm: ComponentInstance, props: Record<any, any> = {}) {
  const setup = vm.$options.setup!
  const ctx = createSetupContext(vm)
  const instance = toVue3ComponentInstance(vm)
  instance.setupContext = ctx
  
  def(props, &#39;__ob__&#39;, createObserver())
  resolveScopedSlots(vm, ctx.slots)

  let binding: ReturnType<SetupFunction<Data, Data>> | undefined | null
  activateCurrentInstance(instance, () => {
    binding = setup(props, ctx)
  })

   // setup返回是函數(shù)的情況 需要重寫render函數(shù)

  const bindingObj = binding

  Object.keys(bindingObj).forEach((name) => {
    let bindingValue: any = bindingObj[name]

    // 數(shù)據(jù)處理
    
    asVmProperty(vm, name, bindingValue)
  })
  return
  }
}

這個(gè)函數(shù)比較長(zhǎng),不在本次要講解的主線上代碼邏輯都刪除了,這個(gè)函數(shù)主要是創(chuàng)建了 ctx 和把 vm 實(shí)例轉(zhuǎn)換成 Vue3 數(shù)據(jù)類型定義的 instance ,然后執(zhí)行 setup 函數(shù)得到返回值,然后遍歷每個(gè)屬性,調(diào)用 asVmProperty 掛載到 vm 上面,當(dāng)然這里的掛載不是直接通過把屬性和值添加到 vm 上面,這么做會(huì)有一個(gè)問題,就是后續(xù)對(duì)該屬性的修改不能同步到 vm 中,這里采用的還是 Vue 最常見的數(shù)據(jù)代理。

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
        },
      })
    }
}

看到這里,相信你已經(jīng)明白了在 setup 中定義返回的為什么能夠在 template 、 datamethods 等之中去使用了,因?yàn)榉祷氐臇|西都已經(jīng)被代理到 vm 之上了。

響應(yīng)式( ref reactive 的實(shí)現(xiàn))

接下來我們來說說響應(yīng)式相關(guān)的,為什么 refreactive 也可以讓數(shù)據(jù)成為響應(yīng)式的。

ref 的實(shí)現(xiàn)其實(shí)是對(duì) 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),
  })
}

因?yàn)?reactive 接受的必須是一個(gè)對(duì)象,所有這里使用了一個(gè)常量作為 refkey, 也就是

const value = reactive({
  "composition-api.refKey": row
})
export function createRef<T>(
  options: RefOption<T>,
  isReadonly = false,
  isComputed = false
): RefImpl<T> {
  const r = new RefImpl<T>(options)

  const sealed = Object.seal(r)
  if (isReadonly) readonlySet.set(sealed, true)
  return sealed
}

export class RefImpl<T> implements Ref<T> {
  readonly [_refBrand]!: true
  public value!: T
  constructor({ get, set }: RefOption<T>) {
    proxy(this, &#39;value&#39;, {
      get,
      set,
    })
  }
}

通過 new RefImpl 實(shí)例,該實(shí)例上有一個(gè) value 的屬性,對(duì) value 做代理,當(dāng)取值的時(shí)候返回 value[RefKey],賦值的時(shí)候賦值給 value[RefKey], 這就是為什么 ref 可以用在基本類型,然后對(duì)返回值的 .value 進(jìn)行操作。調(diào)用 object.seal 是把對(duì)象密封起來(會(huì)讓這個(gè)對(duì)象變的不能添加新屬性,且所有已有屬性會(huì)變的不可配置。屬性不可配置的效果就是屬性變的不可刪除,以及一個(gè)數(shù)據(jù)屬性不能被重新定義成為訪問器屬性,或者反之。但屬性的值仍然可以修改。)

我們主要看下 reactive 的實(shí)現(xiàn)

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 定義的數(shù)據(jù),最終還是通過了變成了一個(gè) observed 實(shí)例對(duì)象,也就是 Vue2 在對(duì) data 進(jìn)行處理時(shí),會(huì)調(diào)用 observe 返回的一樣,這里在 Vue2.6+observe 函數(shù)向外暴露為 Vue.observable,如果是低版本的話,可以通過重新 new 一個(gè) vue 實(shí)例,借助 data 也可以返回一個(gè) observed 實(shí)例,如上述代碼。

因?yàn)樵?reactive 中定義的數(shù)據(jù),就如你在 data 中定義的數(shù)據(jù)一樣,都是在操作返回的 observed ,當(dāng)你取值的時(shí)候,會(huì)觸發(fā) getter 進(jìn)行依賴收集,賦值時(shí)會(huì)調(diào)用 setter 去派發(fā)更新, 只是定義在 setup 中,結(jié)合之前講到的 setup 部分,比如當(dāng)我們?cè)?template 中訪問一個(gè)變量的值時(shí),vm.foo -> proxysetup 里面的 foo -> observedfoo ,完成取值的流程,這會(huì)比直接在 data 上多代理了一層,因此整個(gè)過程也會(huì)有額外的性能開銷。

因此使用該 API 也不會(huì)讓你可以直接規(guī)避掉 vue2 響應(yīng)式數(shù)據(jù)定義的約束,因?yàn)樽罱K還是用 Object.defineProperty 去做對(duì)象攔截,插件同樣也提供了 set API 讓你去操作對(duì)象新增屬性等操作。

總結(jié)

通過上面的了解,相信你一定對(duì)于 Vue2 如何使用 composition API 有了一定的了解,因?yàn)?API 相當(dāng)多, 響應(yīng)式相關(guān)的就還有 toRefs、toRef、unref、shallowRef、triggerRef 等等,這里就不一一分析,有興趣的可以繼續(xù)看源碼的實(shí)現(xiàn)。

Vue2 的同學(xué)也可以不用羨慕寫 Vue3 的同學(xué)了,直接引入到項(xiàng)目就可以使用起來,雖然沒有 vue3 那么好的體驗(yàn),但是絕大部分場(chǎng)景還是相同的,使用時(shí)注意 README 文檔最后的限制章節(jié),里面講了一些使用限制。

(學(xué)習(xí)視頻分享:vuejs入門教程、編程基礎(chǔ)視頻

以上是解析Vue2實(shí)現(xiàn)composition API的原理的詳細(xì)內(nèi)容。更多信息請(qǐng)關(guān)注PHP中文網(wǎng)其他相關(guān)文章!

本站聲明
本文內(nèi)容由網(wǎng)友自發(fā)貢獻(xiàn),版權(quán)歸原作者所有,本站不承擔(dān)相應(yīng)法律責(zé)任。如您發(fā)現(xiàn)有涉嫌抄襲侵權(quán)的內(nèi)容,請(qǐng)聯(lián)系admin@php.cn

熱AI工具

Undress AI Tool

Undress AI Tool

免費(fèi)脫衣服圖片

Undresser.AI Undress

Undresser.AI Undress

人工智能驅(qū)動(dòng)的應(yīng)用程序,用于創(chuàng)建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用于從照片中去除衣服的在線人工智能工具。

Clothoff.io

Clothoff.io

AI脫衣機(jī)

Video Face Swap

Video Face Swap

使用我們完全免費(fèi)的人工智能換臉工具輕松在任何視頻中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費(fèi)的代碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

功能強(qiáng)大的PHP集成開發(fā)環(huán)境

Dreamweaver CS6

Dreamweaver CS6

視覺化網(wǎng)頁開發(fā)工具

SublimeText3 Mac版

SublimeText3 Mac版

神級(jí)代碼編輯軟件(SublimeText3)

熱門話題

Laravel 教程
1600
29
PHP教程
1502
276
PHP與Vue:完美搭檔的前端開發(fā)利器 PHP與Vue:完美搭檔的前端開發(fā)利器 Mar 16, 2024 pm 12:09 PM

PHP與Vue:完美搭檔的前端開發(fā)利器在當(dāng)今互聯(lián)網(wǎng)高速發(fā)展的時(shí)代,前端開發(fā)變得愈發(fā)重要。隨著用戶對(duì)網(wǎng)站和應(yīng)用的體驗(yàn)要求越來越高,前端開發(fā)人員需要使用更加高效和靈活的工具來創(chuàng)建響應(yīng)式和交互式的界面。PHP和Vue.js作為前端開發(fā)領(lǐng)域的兩個(gè)重要技術(shù),搭配起來可以稱得上是完美的利器。本文將探討PHP和Vue的結(jié)合,以及詳細(xì)的代碼示例,幫助讀者更好地理解和應(yīng)用這兩

Go語言前端技術(shù)探秘:前端開發(fā)新視野 Go語言前端技術(shù)探秘:前端開發(fā)新視野 Mar 28, 2024 pm 01:06 PM

Go語言作為一種快速、高效的編程語言,在后端開發(fā)領(lǐng)域廣受歡迎。然而,很少有人將Go語言與前端開發(fā)聯(lián)系起來。事實(shí)上,使用Go語言進(jìn)行前端開發(fā)不僅可以提高效率,還能為開發(fā)者帶來全新的視野。本文將探討使用Go語言進(jìn)行前端開發(fā)的可能性,并提供具體的代碼示例,幫助讀者更好地了解這一領(lǐng)域。在傳統(tǒng)的前端開發(fā)中,通常會(huì)使用JavaScript、HTML和CSS來構(gòu)建用戶界面

vue.js vs.反應(yīng):特定于項(xiàng)目的考慮因素 vue.js vs.反應(yīng):特定于項(xiàng)目的考慮因素 Apr 09, 2025 am 12:01 AM

Vue.js適合中小型項(xiàng)目和快速迭代,React適用于大型復(fù)雜應(yīng)用。1)Vue.js易于上手,適用于團(tuán)隊(duì)經(jīng)驗(yàn)不足或項(xiàng)目規(guī)模較小的情況。2)React的生態(tài)系統(tǒng)更豐富,適合有高性能需求和復(fù)雜功能需求的項(xiàng)目。

前端面試官常問的問題 前端面試官常問的問題 Mar 19, 2024 pm 02:24 PM

在前端開發(fā)面試中,常見問題涵蓋廣泛,包括HTML/CSS基礎(chǔ)、JavaScript基礎(chǔ)、框架和庫、項(xiàng)目經(jīng)驗(yàn)、算法和數(shù)據(jù)結(jié)構(gòu)、性能優(yōu)化、跨域請(qǐng)求、前端工程化、設(shè)計(jì)模式以及新技術(shù)和趨勢(shì)。面試官的問題旨在評(píng)估候選人的技術(shù)技能、項(xiàng)目經(jīng)驗(yàn)以及對(duì)行業(yè)趨勢(shì)的理解。因此,應(yīng)試者應(yīng)充分準(zhǔn)備這些方面,以展現(xiàn)自己的能力和專業(yè)知識(shí)。

Golang與前端技術(shù)結(jié)合:探討Golang如何在前端領(lǐng)域發(fā)揮作用 Golang與前端技術(shù)結(jié)合:探討Golang如何在前端領(lǐng)域發(fā)揮作用 Mar 19, 2024 pm 06:15 PM

Golang與前端技術(shù)結(jié)合:探討Golang如何在前端領(lǐng)域發(fā)揮作用,需要具體代碼示例隨著互聯(lián)網(wǎng)和移動(dòng)應(yīng)用的快速發(fā)展,前端技術(shù)也愈發(fā)重要。而在這個(gè)領(lǐng)域中,Golang作為一門強(qiáng)大的后端編程語言,也可以發(fā)揮重要作用。本文將探討Golang如何與前端技術(shù)結(jié)合,以及通過具體的代碼示例來展示其在前端領(lǐng)域的潛力。Golang在前端領(lǐng)域的作用作為一門高效、簡(jiǎn)潔且易于學(xué)習(xí)的

Vue.js很難學(xué)習(xí)嗎? Vue.js很難學(xué)習(xí)嗎? Apr 04, 2025 am 12:02 AM

Vue.js不難學(xué),特別是對(duì)于有JavaScript基礎(chǔ)的開發(fā)者。1)其漸進(jìn)式設(shè)計(jì)和響應(yīng)式系統(tǒng)簡(jiǎn)化了開發(fā)過程。2)組件化開發(fā)讓代碼管理更高效。3)使用示例展示了基本和高級(jí)用法。4)常見錯(cuò)誤可以通過VueDevtools調(diào)試。5)性能優(yōu)化和最佳實(shí)踐如使用v-if/v-show和key屬性可提升應(yīng)用效率。

VUE是用于前端還是后端? VUE是用于前端還是后端? Apr 03, 2025 am 12:07 AM

Vue.js主要用于前端開發(fā)。1)它是一個(gè)輕量級(jí)且靈活的JavaScript框架,專注于構(gòu)建用戶界面和單頁面應(yīng)用。2)Vue.js的核心是其響應(yīng)式數(shù)據(jù)系統(tǒng),數(shù)據(jù)變化時(shí)視圖自動(dòng)更新。3)它支持組件化開發(fā),UI可拆分為獨(dú)立、可復(fù)用的組件。

了解React的主要功能:前端視角 了解React的主要功能:前端視角 Apr 18, 2025 am 12:15 AM

React的主要功能包括組件化思想、狀態(tài)管理和虛擬DOM。1)組件化思想允許將UI拆分成可復(fù)用的部分,提高代碼可讀性和可維護(hù)性。2)狀態(tài)管理通過state和props管理動(dòng)態(tài)數(shù)據(jù),變化觸發(fā)UI更新。3)虛擬DOM優(yōu)化性能,通過內(nèi)存中的DOM副本計(jì)算最小操作更新UI。

See all articles