Analyser le principe de mise en ?uvre de l'API de composition de Vue2
Jan 13, 2023 am 08:30 AM自從 Vue3
發(fā)布之后,composition API
這個(gè)詞走入寫(xiě) Vue
同學(xué)的視野之中,相信大家也一直聽(tīng)到 composition API
比之前的 options API
有多好多強(qiáng),如今由于 @vue/composition-api
插件的發(fā)布,Vue2
的同學(xué)也可以上車(chē)咯,接下來(lái)我們主要以響應(yīng)式的 ref
和 reactive
來(lái)深入分析一下,這個(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 } } })
怎么樣,看完是不是感覺(jué)和 vue3
一模一樣,你可能會(huì)想:
這是
vue2
啊,我之前的data
、methods
里面也有變量和方法,怎么做到跟setup
返回值打通合并在一起的。【相關(guān)推薦:vuejs視頻教程、web前端開(kāi)發(fā)】vue2
不是只有定義在data
里面的數(shù)據(jù)才會(huì)被處理成響應(yīng)式的嗎?ref
和reactive
是怎么做到的呢?vue2
響應(yīng)式數(shù)據(jù)定義的約束(添加賦值原對(duì)象沒(méi)有的屬性,數(shù)組下標(biāo)修改等),改用ref
和reactive
就沒(méi)問(wèn)題嗎?
當(dāng)然還有很多的疑惑,因?yàn)椴寮峁┑?API
相當(dāng)多,覆蓋了絕大部分 Vue3
所擁有的,這里主要從這幾個(gè)問(wèn)題來(lái)分析一下是如何做到的。
原理解析
得益于 Vue
的插件系統(tǒng),@vue/composition-api
像 vue-router
、vuex
一樣也是通過(guò)官方提供的插件式來(lái)注入。
// 這里只貼跟本章要講的相關(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ù)。
接下來(lái)主要看下 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)?Vue
在 beforeCreated
和 created
生命周期之間,會(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)行包裹。
接下來(lái)看 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, '__ob__', createObserver()) resolveScopedSlots(vm, ctx.slots) let binding: ReturnType<SetupFunction<Data, Data>> | undefined | null activateCurrentInstance(instance, () => { binding = setup(props, ctx) }) // setup返回是函數(shù)的情況 需要重寫(xiě)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),不在本次要講解的主線(xiàn)上代碼邏輯都刪除了,這個(gè)函數(shù)主要是創(chuàng)建了 ctx
和把 vm
實(shí)例轉(zhuǎn)換成 Vue3
數(shù)據(jù)類(lèi)型定義的 instance
,然后執(zhí)行 setup
函數(shù)得到返回值,然后遍歷每個(gè)屬性,調(diào)用 asVmProperty
掛載到 vm
上面,當(dāng)然這里的掛載不是直接通過(guò)把屬性和值添加到 vm
上面,這么做會(huì)有一個(gè)問(wèn)題,就是后續(xù)對(duì)該屬性的修改不能同步到 vm
中,這里采用的還是 Vue
最常見(jiàn)的數(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
、 data
、 methods
等之中去使用了,因?yàn)榉祷氐臇|西都已經(jīng)被代理到 vm
之上了。
響應(yīng)式( ref
reactive
的實(shí)現(xiàn))
接下來(lái)我們來(lái)說(shuō)說(shuō)響應(yīng)式相關(guān)的,為什么 ref
和 reactive
也可以讓數(shù)據(jù)成為響應(yīng)式的。
ref
的實(shí)現(xiàn)其實(shí)是對(duì) reactive
再次封裝,主要用來(lái)給基本類(lèi)型使用。
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è)常量作為 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, 'value', { get, set, }) } }
通過(guò) new RefImpl
實(shí)例,該實(shí)例上有一個(gè) value
的屬性,對(duì) value
做代理,當(dāng)取值的時(shí)候返回 value[RefKey]
,賦值的時(shí)候賦值給 value[RefKey]
, 這就是為什么 ref
可以用在基本類(lèi)型,然后對(duì)返回值的 .value
進(jìn)行操作。調(diào)用 object.seal
是把對(duì)象密封起來(lái)(會(huì)讓這個(gè)對(duì)象變的不能添加新屬性,且所有已有屬性會(huì)變的不可配置。屬性不可配置的效果就是屬性變的不可刪除,以及一個(gè)數(shù)據(jù)屬性不能被重新定義成為訪(fǎng)問(wèn)器屬性,或者反之。但屬性的值仍然可以修改。)
我們主要看下 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 }
我們通過(guò) ref
或者 reactive
定義的數(shù)據(jù),最終還是通過(guò)了變成了一個(gè) observed
實(shí)例對(duì)象,也就是 Vue2
在對(duì) data
進(jìn)行處理時(shí),會(huì)調(diào)用 observe
返回的一樣,這里在 Vue2.6+
把observe
函數(shù)向外暴露為 Vue.observable
,如果是低版本的話(huà),可以通過(guò)重新 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)行依賴(lài)收集,賦值時(shí)會(huì)調(diào)用 setter
去派發(fā)更新,
只是定義在 setup
中,結(jié)合之前講到的 setup
部分,比如當(dāng)我們?cè)?template
中訪(fǎng)問(wèn)一個(gè)變量的值時(shí),vm.foo
-> proxy
到 setup
里面的 foo
-> observed
的 foo
,完成取值的流程,這會(huì)比直接在 data
上多代理了一層,因此整個(gè)過(guò)程也會(huì)有額外的性能開(kāi)銷(xiāo)。
因此使用該 API
也不會(huì)讓你可以直接規(guī)避掉 vue2
響應(yīng)式數(shù)據(jù)定義的約束,因?yàn)樽罱K還是用 Object.defineProperty
去做對(duì)象攔截,插件同樣也提供了 set API
讓你去操作對(duì)象新增屬性等操作。
總結(jié)
通過(guò)上面的了解,相信你一定對(duì)于 Vue2
如何使用 composition API
有了一定的了解,因?yàn)?API
相當(dāng)多, 響應(yīng)式相關(guān)的就還有 toRefs、toRef、unref、shallowRef、triggerRef
等等,這里就不一一分析,有興趣的可以繼續(xù)看源碼的實(shí)現(xiàn)。
寫(xiě) Vue2
的同學(xué)也可以不用羨慕寫(xiě) Vue3
的同學(xué)了,直接引入到項(xiàng)目就可以使用起來(lái),雖然沒(méi)有 vue3
那么好的體驗(yàn),但是絕大部分場(chǎng)景還是相同的,使用時(shí)注意 README
文檔最后的限制章節(jié),里面講了一些使用限制。
(學(xué)習(xí)視頻分享:vuejs入門(mén)教程、編程基礎(chǔ)視頻)
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Outils d'IA chauds

Undress AI Tool
Images de déshabillage gratuites

Undresser.AI Undress
Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover
Outil d'IA en ligne pour supprimer les vêtements des photos.

Clothoff.io
Dissolvant de vêtements AI

Video Face Swap
échangez les visages dans n'importe quelle vidéo sans effort grace à notre outil d'échange de visage AI entièrement gratuit?!

Article chaud

Outils chauds

Bloc-notes++7.3.1
éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise
Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1
Puissant environnement de développement intégré PHP

Dreamweaver CS6
Outils de développement Web visuel

SublimeText3 version Mac
Logiciel d'édition de code au niveau de Dieu (SublimeText3)

PHP et Vue : une combinaison parfaite d'outils de développement front-end à l'ère actuelle de développement rapide d'Internet, le développement front-end est devenu de plus en plus important. Alors que les utilisateurs ont des exigences de plus en plus élevées en matière d’expérience des sites Web et des applications, les développeurs front-end doivent utiliser des outils plus efficaces et plus flexibles pour créer des interfaces réactives et interactives. En tant que deux technologies importantes dans le domaine du développement front-end, PHP et Vue.js peuvent être considérés comme une arme parfaite lorsqu'ils sont associés. Cet article explorera la combinaison de PHP et Vue, ainsi que des exemples de code détaillés pour aider les lecteurs à mieux comprendre et appliquer ces deux éléments.

En tant que langage de programmation rapide et efficace, le langage Go est très populaire dans le domaine du développement back-end. Cependant, peu de gens associent le langage Go au développement front-end. En fait, l’utilisation du langage Go pour le développement front-end peut non seulement améliorer l’efficacité, mais également ouvrir de nouveaux horizons aux développeurs. Cet article explorera la possibilité d'utiliser le langage Go pour le développement front-end et fournira des exemples de code spécifiques pour aider les lecteurs à mieux comprendre ce domaine. Dans le développement front-end traditionnel, JavaScript, HTML et CSS sont souvent utilisés pour créer des interfaces utilisateur.

Vue.js convient aux projets de petite et moyenne taille et aux itérations rapides, tandis que React convient aux applications grandes et complexes. 1) Vue.js est facile à utiliser et convient aux situations où l'équipe est insuffisante ou l'échelle du projet est petite. 2) React a un écosystème plus riche et convient aux projets avec des performances élevées et des besoins fonctionnels complexes.

Lors des entretiens de développement front-end, les questions courantes couvrent un large éventail de sujets, notamment les bases HTML/CSS, les bases JavaScript, les frameworks et les bibliothèques, l'expérience du projet, les algorithmes et les structures de données, l'optimisation des performances, les requêtes inter-domaines, l'ingénierie front-end, les modèles de conception et les nouvelles technologies et tendances. Les questions de l'intervieweur sont con?ues pour évaluer les compétences techniques du candidat, son expérience en matière de projet et sa compréhension des tendances du secteur. Par conséquent, les candidats doivent être parfaitement préparés dans ces domaines pour démontrer leurs capacités et leur expertise.

Combinaison de Golang et de la technologie front-end?: pour explorer le r?le de Golang dans le domaine front-end, des exemples de code spécifiques sont nécessaires. Avec le développement rapide d'Internet et des applications mobiles, la technologie front-end est devenue de plus en plus importante. Dans ce domaine, Golang, en tant que puissant langage de programmation back-end, peut également jouer un r?le important. Cet article explorera comment Golang est combiné avec la technologie front-end et démontrera son potentiel dans le domaine front-end à travers des exemples de code spécifiques. Le r?le de Golang dans le domaine front-end est celui d'un outil efficace, concis et facile à apprendre.

Vue.js n'est pas difficile à apprendre, en particulier pour les développeurs avec une fondation JavaScript. 1) Sa conception progressive et son système réactif simplifient le processus de développement. 2) Le développement basé sur les composants rend la gestion du code plus efficace. 3) Les exemples d'utilisation montrent une utilisation de base et avancée. 4) Les erreurs courantes peuvent être déboguées via Vuedevtools. 5) L'optimisation des performances et les meilleures pratiques, telles que l'utilisation des attributs V-IF / V et clés, peuvent améliorer l'efficacité de l'application.

Vue.js est principalement utilisé pour le développement frontal. 1) Il s'agit d'un cadre JavaScript léger et flexible axé sur la construction d'interfaces utilisateur et d'applications à une seule page. 2) Le c?ur de Vue.js est son système de données réactif, et la vue est automatiquement mise à jour lorsque les données changent. 3) Il prend en charge le développement des composants et l'interface utilisateur peut être divisée en composants indépendants et réutilisables.

Les principales fonctions de React incluent la pensée composante, la gestion de l'état et le DOM virtuel. 1) L'idée de la composante permet de diviser l'interface utilisateur en parties réutilisables pour améliorer la lisibilité et la maintenabilité du code. 2) La gestion de l'état gère les données dynamiques via l'état et les accessoires, et les modifications déclenchent des mises à jour de l'interface utilisateur. 3) Performances d'optimisation virtuelle DOM, mettez à jour l'interface utilisateur à travers le calcul du fonctionnement minimum de la réplique DOM en mémoire.
