


Analysieren Sie das Prinzip der Implementierung der Kompositions-API durch Vue2
Seit der Veröffentlichung von Vue3
ist das Wort composition API
in die Vision von Studenten eingedrungen, die Vue
schreiben, und ich glaube Ihnen Ich habe es die ganze Zeit gehört. composition API
ist jetzt aufgrund der Veröffentlichung von @vue/composition-apioptions API
/code>-Plug-in, Vue2
-Studenten können auch in den Bus einsteigen. Als nächstes werden wir hauptsächlich responsive ref
und reactive
für eine gründliche Analyse verwenden wie dieses Plug-in diese Funktion implementiert. Vue3
发布之后,composition API
这个词走入写 Vue
同学的视野之中,相信大家也一直听到 composition API
比之前的 options API
有多好多强,如今由于 @vue/composition-api
插件的发布,Vue2
的同学也可以上车咯,接下来我们主要以响应式的 ref
和 reactive
来深入分析一下,这个插件是怎么实现此功能的。
如何使用
// 入口文件引入并注册 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
啊,我之前的data
、methods
里面也有变量和方法,怎么做到跟setup
返回值打通合并在一起的。【相关推荐:vuejs视频教程、web前端开发】vue2
不是只有定义在data
里面的数据才会被处理成响应式的吗?ref
和reactive
是怎么做到的呢?vue2
响应式数据定义的约束(添加赋值原对象没有的属性,数组下标修改等),改用ref
和reactive
就没问题吗?
当然还有很多的疑惑,因为插件提供的 API
相当多,覆盖了绝大部分 Vue3
所拥有的,这里主要从这几个问题来分析一下是如何做到的。
原理解析
得益于 Vue
的插件系统,@vue/composition-api
像 vue-router
、vuex
一样也是通过官方提供的插件式来注入。
// 这里只贴跟本章要讲的相关代码 funciton mixin (Vue) { Vue.mixin({ beforeCreate: functionApiInit } } function install (Vue) { mixin(Vue); } export const Plugin = { install: (Vue: VueConstructor) => install(Vue), }
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
拿到定义的数据,所以这里重新对该函数其包裹一层,这也是为什么要选择 beforeCreate
钩子注入的一个原因,必须在该函数调用前进行包裹。
接下来看 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返回是函数的情况 需要重写render函数 const bindingObj = binding Object.keys(bindingObj).forEach((name) => { let bindingValue: any = bindingObj[name] // 数据处理 asVmProperty(vm, name, bindingValue) }) return } }
这个函数比较长,不在本次要讲解的主线上代码逻辑都删除了,这个函数主要是创建了 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
、 methods
等之中去使用了,因为返回的东西都已经被代理到 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
Wie benutzt man
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, }) } }
vue3</? code>? Sie denken vielleicht: 🎜<ul><li>🎜Das ist <code>vue2
. Meine vorherigen data
und methods
haben auch Variablen und Methoden . Wie geht das? Es wird mit dem Rückgabewert von setup
zusammengeführt. [Verwandte Empfehlungen: vuejs Video-Tutorial, Web-Frontend-Entwicklung]🎜vue2 </ code> Stimmt es nicht, dass nur die in <code>data
definierten Daten responsiv verarbeitet werden? Wie machen ref
und reactive
das? 🎜vue2
Für Einschränkungen, die durch responsive Daten definiert werden (Hinzufügen von Attributen, die nicht dem ursprünglichen Objekt zugewiesen sind, Ändern von Array-Indizes usw.), verwenden Sie ref</ code> und Ist <code>reaktiv
in Ordnung? 🎜API
und deckt den größten Teil des Vue3
ab > hat, hier Lassen Sie uns anhand dieser Fragen analysieren, wie es gemacht wird. 🎜Prinzipienanalyse
🎜Dank des Plug-in-Systems vonVue
, @vue/ Die Kompositions-API
wird ebenso wie vue-router
und vuex
über offiziell bereitgestellte Plug-Ins injiziert. 🎜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 }
Vue
-Plugin macht eine install
-Methode für die Außenwelt verfügbar. Wenn use
aufgerufen wird, wird diese Methode aufgerufen und Der Vue
-Konstruktor wird als Parameter übergeben und dann wird Vue.mixin
aufgerufen, um die zu verarbeitende Funktion einzumischen, wenn der entsprechende Hook gemischt wird. 🎜🎜Der nächste Schritt besteht darin, zu sehen, was functionApiInit
tut🎜rrreee🎜Denn Vue
befindet sich in beforeCreated
und created</code > Lebenszyklen Dazwischen verarbeitet <code>initState
die Daten, und bei der Verarbeitung von data
wird $options.data
aufgerufen, um die definierten Daten abzurufen Daher wird diese Funktion hier neu umschlossen. Dies ist einer der Gründe, warum die Hook-Injektion beforeCreate
ausgewählt wird. Sie muss vor dem Aufruf der Funktion umschlossen werden.
Schauen wir uns als nächstes an, was initSetup
macht🎜rrreee🎜Diese Funktion ist relativ lang und die Codelogik, die diesmal nicht in der Hauptzeile steht, wurde gelöscht. Diese Funktion erstellt hauptsächlich ctx</code > Und konvertieren Sie die <code>vm
-Instanz in eine instance
, die durch den Datentyp Vue3
definiert ist, und führen Sie dann das setup</ aus. Code>-Funktion, um den Rückgabewert zu erhalten. Anschließend durchlaufen Sie jede Eigenschaft und rufen <code>asVmProperty
auf, um sie auf vm
bereitzustellen. Natürlich erfolgt die Bereitstellung hier nicht durch direktes Hinzufügen von Eigenschaften und Werte zu vm
Oben gibt es ein Problem, das heißt, spätere Änderungen am Attribut können nicht mit vm
synchronisiert werden Hier wird Vue
verwendet. 🎜rrreee🎜Da ich das sehe, glaube ich, dass Sie verstanden haben, warum der in setup
definierte zurückgegebene Wert in template
, data
und methods
wird während des Wartens verwendet, da die zurückgegebenen Dinge an vm
weitergeleitet wurden. 🎜Responsive (Implementierung von ref
reactive
)
🎜Als nächstes lassen wir uns reden über Reaktionsfähigkeit, warum ref
und reactive
auch Daten responsiv machen können. 🎜🎜Die Implementierung von ref
ist eigentlich eine Neukapselung von reactive
, die hauptsächlich für Basistypen verwendet wird. 🎜rrreee🎜Da reactive
ein Objekt akzeptieren muss, wird hier eine Konstante als key
von ref
verwendet, nämlich 🎜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, }) } }
通过 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
-> proxy
到 setup
里面的 foo
-> observed
的 foo
,完成取值的流程,这会比直接在 data
上多代理了一层,因此整个过程也会有额外的性能开销。
因此使用该 API
也不会让你可以直接规避掉 vue2
响应式数据定义的约束,因为最终还是用 Object.defineProperty
去做对象拦截,插件同样也提供了 set API
让你去操作对象新增属性等操作。
总结
通过上面的了解,相信你一定对于 Vue2
如何使用 composition API
有了一定的了解,因为 API
相当多, 响应式相关的就还有 toRefs、toRef、unref、shallowRef、triggerRef
等等,这里就不一一分析,有兴趣的可以继续看源码的实现。
写 Vue2
的同学也可以不用羡慕写 Vue3
的同学了,直接引入到项目就可以使用起来,虽然没有 vue3
那么好的体验,但是绝大部分场景还是相同的,使用时注意 README
文档最后的限制章节,里面讲了一些使用限制。
Das obige ist der detaillierte Inhalt vonAnalysieren Sie das Prinzip der Implementierung der Kompositions-API durch Vue2. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Heiße KI -Werkzeuge

Undresser.AI Undress
KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover
Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool
Ausziehbilder kostenlos

Clothoff.io
KI-Kleiderentferner

AI Hentai Generator
Erstellen Sie kostenlos Ai Hentai.

Heißer Artikel

Heiße Werkzeuge

Notepad++7.3.1
Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version
Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1
Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6
Visuelle Webentwicklungstools

SublimeText3 Mac-Version
Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

Heiße Themen



Der nicht blockierende und ereignisgesteuerte Knotendienst hat den Vorteil eines geringen Speicherverbrauchs und eignet sich sehr gut für die Verarbeitung massiver Netzwerkanforderungen. Unter der Voraussetzung massiver Anfragen müssen Probleme im Zusammenhang mit der „Speicherkontrolle“ berücksichtigt werden. 1. Der Garbage-Collection-Mechanismus und die Speicherbeschränkungen von V8 Js wird von der Garbage-Collection-Maschine gesteuert

PHP und Vue: eine perfekte Kombination von Front-End-Entwicklungstools In der heutigen Zeit der rasanten Entwicklung des Internets ist die Front-End-Entwicklung immer wichtiger geworden. Da Benutzer immer höhere Anforderungen an das Erlebnis von Websites und Anwendungen stellen, müssen Frontend-Entwickler effizientere und flexiblere Tools verwenden, um reaktionsfähige und interaktive Schnittstellen zu erstellen. Als zwei wichtige Technologien im Bereich der Front-End-Entwicklung können PHP und Vue.js in Kombination als perfekte Waffe bezeichnet werden. In diesem Artikel geht es um die Kombination von PHP und Vue sowie um detaillierte Codebeispiele, die den Lesern helfen sollen, diese beiden besser zu verstehen und anzuwenden

Domänenübergreifend ist ein Szenario, das in der Entwicklung häufig vorkommt und auch ein häufig in Interviews diskutiertes Thema ist. Die Beherrschung gängiger domänenübergreifender Lösungen und der dahinter stehenden Prinzipien kann nicht nur unsere Entwicklungseffizienz verbessern, sondern auch in Vorstellungsgesprächen bessere Leistungen erbringen.

Mit der Entwicklung der Internet-Technologie hat die Front-End-Entwicklung immer mehr an Bedeutung gewonnen. Insbesondere die Popularität mobiler Geräte erfordert eine Front-End-Entwicklungstechnologie, die effizient, stabil, sicher und einfach zu warten ist. Als sich schnell entwickelnde Programmiersprache wird die Go-Sprache von immer mehr Entwicklern verwendet. Ist es also möglich, die Go-Sprache für die Front-End-Entwicklung zu verwenden? Als Nächstes wird in diesem Artikel ausführlich erläutert, wie die Go-Sprache für die Front-End-Entwicklung verwendet wird. Werfen wir zunächst einen Blick darauf, warum die Go-Sprache für die Front-End-Entwicklung verwendet wird. Viele Leute denken, dass die Go-Sprache eine ist

In Front-End-Entwicklungsinterviews decken häufige Fragen ein breites Themenspektrum ab, darunter HTML/CSS-Grundlagen, JavaScript-Grundlagen, Frameworks und Bibliotheken, Projekterfahrung, Algorithmen und Datenstrukturen, Leistungsoptimierung, domänenübergreifende Anfragen, Front-End-Engineering, Designmuster sowie neue Technologien und Trends. Interviewerfragen sollen die technischen Fähigkeiten, die Projekterfahrung und das Verständnis des Kandidaten für Branchentrends beurteilen. Daher sollten Kandidaten in diesen Bereichen umfassend vorbereitet sein, um ihre Fähigkeiten und Fachkenntnisse unter Beweis zu stellen.

Django ist ein in Python geschriebenes Webanwendungs-Framework, das Wert auf schnelle Entwicklung und saubere Methoden legt. Obwohl Django ein Web-Framework ist, müssen Sie zur Beantwortung der Frage, ob Django ein Front-End oder ein Back-End ist, ein tiefes Verständnis der Konzepte von Front-End und Back-End haben. Das Front-End bezieht sich auf die Schnittstelle, mit der Benutzer direkt interagieren, und das Back-End bezieht sich auf serverseitige Programme. Sie interagieren mit Daten über das HTTP-Protokoll. Wenn das Front-End und das Back-End getrennt sind, können die Front-End- und Back-End-Programme unabhängig voneinander entwickelt werden, um Geschäftslogik bzw. interaktive Effekte sowie den Datenaustausch zu implementieren.

Als C#-Entwickler umfasst unsere Entwicklungsarbeit in der Regel die Front-End- und Back-End-Entwicklung. Mit der Weiterentwicklung der Technologie und der zunehmenden Komplexität von Projekten wird die gemeinsame Entwicklung von Front-End und Back-End immer wichtiger und komplexer. In diesem Artikel werden einige kollaborative Front-End- und Back-End-Entwicklungstechniken vorgestellt, um C#-Entwicklern dabei zu helfen, die Entwicklungsarbeit effizienter abzuschließen. Nach der Festlegung der Schnittstellenspezifikationen ist die gemeinsame Entwicklung von Front-End und Backend untrennbar mit dem Zusammenspiel der API-Schnittstellen verbunden. Um den reibungslosen Ablauf der kollaborativen Front-End- und Back-End-Entwicklung sicherzustellen, ist es am wichtigsten, gute Schnittstellenspezifikationen zu definieren. Bei der Schnittstellenspezifikation handelt es sich um den Namen der Schnittstelle

Golang kann als Front-End verwendet werden. Golang ist eine sehr vielseitige Programmiersprache, mit der verschiedene Arten von Anwendungen entwickelt werden können, einschließlich Front-End-Anwendungen Eine Reihe von Problemen, die durch Sprachen wie JavaScript verursacht werden. Zum Beispiel Probleme wie schlechte Typsicherheit, geringe Leistung und schwierig zu wartender Code.
