一、Vue3 Composition API是什么?

Composition API是Vue3中外围逻辑及代码组织办法。Vue外围团队将Composition API形容为:一组基于性能的附加API,能够灵便的组合组件的逻辑。在基于Vue2开发我的项目时,通过methods、watch、data等组件属性实现页面逻辑的形式称之为Option API。Option API模式不仅导致组件业务扩散、产生胶水代码,而且编写的代码也须要Vue编译器将JS代码转换为真正的执行代码。Composition API通过将组件属性作为JS函数裸露进去以解决上述问题,通过Composition API实现的业务代码无需编译器两头解决,同时TypeScript的类型查看机制能够更好的保障代码的强壮。

图1 Composition API次要性能函数

二、通过例子理解Composition API应用形式

在这个mini版本的TodoList组件中,首先引入了reactive、Refs、onMounted三个函数,其中reactive次要是用来创立响应式对象,toRefs次要是解决响应式对象因解构赋值导致响应式生效的问题,onMounted则用来拜访mounted挂载组件时的钩子函数。

其次,定义DataPros的接口类型,通过这个接口类型能够获取reactive中定义的属性类型及函数的参数、返回值类型。setup函数是一个新的Vue组件对象,是组件应用Composition API的入口,setup函数蕴含两个参数,第一个是用来获取父组件传值的props,第二个content参数代表组件的上下文对象。这里须要留神的是this在setup中无奈应用。在setup中咱们定义了一个数据类型为DataProps名称为data的响应式对象,对象内蕴含两个参数和两个业务办法,这些定义的属性和办法都在reactive创立的响应式对象中,从而防止了参数定义和逻辑定义拆散的问题。

最初,通过toRefs组件,对data对象进行包装,使其在解构赋值后不会失落响应式个性,并通过return将数据合并到组件模板渲染上下文。

三、应用Composition API模块化共享属性和办法

在Vue2我的项目中,若想在别的组件共享一些属性和代码能够通过mixins(混入)和scoped slots这两种形式实现,然而这两种形式都存在缺点。mixins最大的缺点在于咱们对其在组件中注入的属性和办法无所不知,更无奈实现类型推断,且混入的内容可能与以后组件存在抵触(Vue2有一套欠缺的优先级排列,但熟记较有难度)。scope slots通过v-slot属性精确晓得调用者获取了哪些属性,但只能在template中拜访,且只能在以后组件的作用域应用。上面咱们来看怎么通过Composition API共享属性和办法:

通过引入ref函数,创立了一个名为nowTime的属性,并创立了一个名为getNowTime的办法,而后咱们就能够在任意组件中通过import的形式进行代码共享。这种共享代码的形式既不受模板和组件范畴的限度,也将受害于编译器类型查看机制。值得一提的是,在Vue3中Vuex也能够采纳此函数式的形式援用,无需净化Vue原型。

四、Composition API响应式对象实现源码剖析

在Vue3 Composition API中,创立响应式对象能够通过reactive API和ref API来实现,接下来咱们将通过源码剖析reactive API创立响应式对象的形式(ref API的实现外围也是基于reactive API)。

在GitHub上拉取vue-next仓库,能查看Vue3的源代码。开展vue-next/packages/reactivity/src/reactive.ts门路,能看reactive函数的定义。通过reactive的类型申明,咱们能够看到函数接管一个类型为泛型T的参数,而这个泛型继承自object,故target的类型为object类或为其子类。返回类型为UnwrapNestedRefs类型,该类型将判断返回的对象是否继承自Ref对象,如果为否则可能为嵌套的Ref对象,需用递归解套。进入reactive函数外部,咱们看到如果传入的对象为只读则返回对象自身,否则返回createReactiveObject,执行创立响应式对象。

在createReactiveObject函数中,会判断target对象是否为对象类型,如果不是则间接返回,开发模式下会在控制台打印正告。接着会判断指标是否曾经为Proxy对象,是的话同样返回。通过以上查看后,代码会创立一个新的proxy对象来实现对象的响应式,proxy对象会依据对象的类型抉择应用collectionHandlers还是baseHandlers。

创立响应式对象外围在于实现get、set以及其余相干的陷阱函数,reactive基于Proxy实现了这些陷阱函数,并解决了因应用Object.defineProperty()办法导致的对象属性增加删除、组件下标批改等操作无奈被监听的问题。鉴于篇幅起因,本文仅剖析baseHandlers包装响应式数据的实现原理。

createGetter对象用来生成响应式对象的get办法(即get陷阱函数),通过Reflect反射获取到对象的原始属性当前,会判断对象是否为内置办法,如果为内置办法则不进行代理操作,并在属性不为readOnly的状况下执行依赖收集操作,最初通过递归调用,返回响应式get对象。

接下来咱们来看reactive如何实现对象的set陷阱函数。函数首先会判断原来的数据是否为ref对象,若为是则间接将新数据赋值给ref.value即可(这便是用reactive创立的响应式数据不须要用.value取值的起因)。程序会判断key是否存在,如果不存在则通过trigger执行ADD操作,否则通过trigger执行SET操作。Trigger办法在框架中表演通信员的角色,贯通整个零碎,使得ref 具备高度的响应性。

五、总结

本文以”什么是Composition API”开篇,介绍了Composition API的具体内容及劣势;而后通过应用Composition API创立的mini TodoList组件,理解了Composition API的应用形式及如何通过组件化共享代码。最初,通过源码剖析了reactive API的实现形式。本文旨在通过剖析Composition API来帮忙大家更好的了解Vue3前端框架,因为意识的局限性可能存在相应疏漏,望大家批评指正。