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

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

解析Vue2實(shí)作composition API的原理

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

解析Vue2實(shí)作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 啊,我之前的datamethods 裡面也有變數(shù)和方法,怎麼做到跟setup 傳回值打通合併在一起的。 【相關(guān)推薦:vuejs影片教學(xué)、web前端開發(fā)

  • vue2 不是只有定義在 data 裡面的資料才會(huì)被處理成響應(yīng)式的嗎? refreactive 是怎麼做到的呢?

  • vue2 響應(yīng)式資料定義的約束(新增賦值原始物件沒有的屬性,陣列下標(biāo)修改等),改用refreactive 就沒問題嗎?

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

原理解析

得益於Vue 的外掛系統(tǒng),@vue/composition-api 像是 vue-routervuex 一樣也是透過官方提供的外掛程式來注入。

// 這里只貼跟本章要講的相關(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)呼叫use 的時(shí)候會(huì)呼叫該方法,並且把Vue 建構(gòu)子作為參數(shù)傳入,然後呼叫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)?code>Vue 在beforeCreatedcreated 生命週期之間,會(huì)initState 對(duì)資料進(jìn)行處理,其中對(duì)data的處理時(shí)就會(huì)呼叫$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ù)比較長,不在本次要講解的主線上程式碼邏輯都刪除了,這個(gè)函數(shù)主要是創(chuàng)建了ctx 和把vm 實(shí)例轉(zhuǎn)換成Vue3 資料型別定義的instance ,然後執(zhí)行setup 函數(shù)得到回??傳值,然後遍歷每個(gè)屬性,呼叫asVmProperty 掛載到vm 上面,當(dāng)然這裡的掛載不是直接透過把屬性和值加到vm 上面,這麼做會(huì)有一個(gè)問題,就是後續(xù)對(duì)該屬性的修改不能同步到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
        },
      })
    }
}

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

回應(yīng)式( ref ?reactive 的實(shí)作)

接下來我們來說說響應(yīng)式相關(guān)的,為什麼refreactive 也可以讓資料成為響應(yīng)式的。

ref 的實(shí)作其實(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è)常數(shù)作為 ref# 的 key, 也就是

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í)作composition API的原理的詳細(xì)內(nèi)容。更多資訊請(qǐng)關(guān)注PHP中文網(wǎng)其他相關(guān)文章!

本網(wǎng)站聲明
本文內(nèi)容由網(wǎng)友自願(yuàn)投稿,版權(quán)歸原作者所有。本站不承擔(dān)相應(yīng)的法律責(zé)任。如發(fā)現(xiàn)涉嫌抄襲或侵權(quán)的內(nèi)容,請(qǐng)聯(lián)絡(luò)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脫衣器

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)

PHP與Vue:完美搭檔的前端開發(fā)利器 PHP與Vue:完美搭檔的前端開發(fā)利器 Mar 16, 2024 pm 12:09 PM

PHP與Vue:完美搭檔的前端開發(fā)利器在當(dāng)今網(wǎng)路快速發(fā)展的時(shí)代,前端開發(fā)變得愈發(fā)重要。隨著使用者對(duì)網(wǎng)站和應(yīng)用的體驗(yàn)要求越來越高,前端開發(fā)人員需要使用更有效率和靈活的工具來創(chuàng)建響應(yīng)式和互動(dòng)式的介面。 PHP和Vue.js作為前端開發(fā)領(lǐng)域的兩個(gè)重要技術(shù),搭配起來可以稱得上是完美的利器。本文將探討PHP和Vue的結(jié)合,以及詳細(xì)的程式碼範(fàn)例,幫助讀者更好地理解和應(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ā)的可能性,並提供具體的程式碼範(fàn)例,幫助讀者更了解這一領(lǐng)域。在傳統(tǒng)的前端開發(fā)中,通常會(huì)使用JavaScript、HTML和CSS來建立使用者介面

Django是前端還是後端?一探究竟! Django是前端還是後端?一探究竟! Jan 19, 2024 am 08:37 AM

Django是一個(gè)由Python編寫的web應(yīng)用框架,它強(qiáng)調(diào)快速開發(fā)和乾淨(jìng)方法。儘管Django是web框架,但要回答Django是前端還是後端這個(gè)問題,需要深入理解前後端的概念。前端是指使用者直接和互動(dòng)的介面,後端是指伺服器端的程序,他們透過HTTP協(xié)定進(jìn)行資料的互動(dòng)。在前端和後端分離的情況下,前後端程式可以獨(dú)立開發(fā),分別實(shí)現(xiàn)業(yè)務(wù)邏輯和互動(dòng)效果,資料的交

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

C#開發(fā)經(jīng)驗(yàn)分享:前端與後端協(xié)同開發(fā)技巧 C#開發(fā)經(jīng)驗(yàn)分享:前端與後端協(xié)同開發(fā)技巧 Nov 23, 2023 am 10:13 AM

身為C#開發(fā)者,我們的開發(fā)工作通常包括前端和後端的開發(fā),而隨著技術(shù)的發(fā)展和專案的複雜性提高,前端與後端協(xié)同開發(fā)也變得越來越重要和複雜。本文將分享一些前端與後端協(xié)同開發(fā)的技巧,以幫助C#開發(fā)者更有效率地完成開發(fā)工作。確定好介面規(guī)範(fàn)前後端的協(xié)同開發(fā)離不開API介面的交互。要確保前後端協(xié)同開發(fā)順利進(jìn)行,最重要的是定義好介面規(guī)格。接口規(guī)範(fàn)涉及到接口的命

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

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

Django:前端和後端開發(fā)都能搞定的神奇框架! Django:前端和後端開發(fā)都能搞定的神奇框架! Jan 19, 2024 am 08:52 AM

Django:前端和後端開發(fā)都能搞定的神奇框架! Django是一個(gè)高效、可擴(kuò)展的網(wǎng)路應(yīng)用程式框架。它能夠支援多種Web開發(fā)模式,包括MVC和MTV,可以輕鬆地開發(fā)出高品質(zhì)的Web應(yīng)用程式。 Django不僅支援後端開發(fā),還能夠快速建構(gòu)出前端的介面,透過模板語言,實(shí)現(xiàn)靈活的視圖展示。 Django把前端開發(fā)和後端開發(fā)融合成了一種無縫的整合,讓開發(fā)人員不必專門學(xué)習(xí)

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

See all articles