组合式API介绍
组合式API是Vue3中引入的一种新的编程模式,它提供了一种更灵活、更高效的方式来组织和复用代码。组合式API的主要目标是解决Vue2中选项式API在处理复杂组件时可能遇到的问题,如逻辑复用和代码组织等。
Vue3引入组合式API的原因在于,随着应用程序的复杂性增加,我们可能会遇到需要在多个组件之间共享状态逻辑的情况。在Vue2中,我们通常会使用mixins来实现这一点,但这可能会导致命名冲突和来源不明的问题。组合式API通过引入setup
函数,使我们能够更直观地组织和复用代码。
总得来说:组合式 API (Composition API) 是一系列 API 的集合,使我们可以使用函数而不是声明选项的方式书写 Vue 组件。它是一个概括性的术语,涵盖了以下方面的 API:
- **响应式 API:**例如 ref() 和 reactive(),使我们可以直接创建响应式状态、计算属性和侦听器。
- **生命周期钩子:**例如 onMounted() 和 onUnmounted(),使我们可以在组件各个生命周期阶段添加逻辑。
- **依赖注入:**例如 provide() 和 inject(),使我们可以在使用响应式 API 时,利用 Vue 的依赖注入系统。
组合式API与选项式API对比
与传统的选项式API相比,组合式API提供了更高的灵活性和可复用性。在选项式API中,我们需要按照data
、methods
、computed
等选项来组织代码,这在处理简单组件时非常方便,但在处理复杂组件时,相关的逻辑可能会被分散在不同的选项中,使得代码难以维护。
相反,组合式API允许我们按照逻辑关系来组织代码,这使得代码更易于理解和维护。此外,组合式API还提供了更好的类型推断,使得我们能够更好地利用TypeScript的优势。
Composition API相比Options API具有以下优势:
- **更好的代码组织:**Composition API允许我们将逻辑相关的代码组织在一起,使得代码更加可读、可维护。
- **更好的复用性:**通过自定义组合函数,我们可以将逻辑进行封装,使其在不同组件之间进行复用。
- **更好的类型推断:**Composition API使用了TypeScript的方式来定义函数签名,可以提供更好的类型推断和编码支持。
- **更小的生产包体积:**搭配
<script setup>
使用组合式 API 比等价情况下的选项式 API 更高效,对代码压缩也更友好。 - **更好的响应性:**Composition API提供了更细粒度的响应性跟踪,可以更好地控制组件的更新和渲染。
观察下面两张动图,直观的感受组合式API与选项式API的最大的区别;
组合式API使用举例
让我们通过一个简单的例子来看看如何使用组合式API。假设我们正在构建一个计数器应用,我们可以使用ref
函数来创建一个响应式的计数器:
javascript
import { ref } from 'vue'
export default {
setup() {
const count = ref(0)
function changeCount() {
count.value++
}
return {
count,
increment
}
}
}
在这个例子中,我们首先导入了ref
函数,然后在setup
函数中使用它来创建一个响应式的计数器。我们还定义了一个increment
函数来增加计数器的值。最后,我们返回了count
和increment
,使得它们可以在模板中使用。
响应式数据
在Vue中,响应式数据是一种可以自动更新UI的数据。Vue3提供了两种创建响应式数据的方法:ref
和reactive
。
ref
函数可以创建一个响应式的数据对象,这个对象有一个value
属性,我们可以通过这个属性来获取或设置它的值。reactive
函数则可以创建一个响应式的对象,我们可以直接访问或修改这个对象的属性。
监听器和计算属性
在Vue中,我们可以使用监听器来响应数据的变化。监听器是一种特殊的计算属性,它会在依赖的数据变化时执行一段代码。我们可以使用watch
函数来创建一个监听器。
typescript
<script setup lang="ts">
import { watch, ref } from 'vue';
const count = ref(0);
const changeCount = () => {
count.value++;
}
// 监听count,计算count的2倍的值,count变化,也自动触发doubleCount值的变化
const doubleCount = ref(0);
watch(() => count, () => {
doubleCount.value = count.value * 2;
});
</script>
计算属性是一种基于其他数据自动计算的数据。我们可以使用computed
函数来创建一个计算属性。与监听器不同,计算属性不会执行任何副作用,它只是根据依赖的数据计算一个新的值。
typescript
<script setup lang="ts">
import { reactive, computed } from 'vue';
interface Name {
firstName: string
lastName: string
}
const person: Name = reactive({
firstName: 'zhang',
lastName: 'san'
})
// personName 由firstName和lastName计算得来
const personName = computed(() => {
return person.firstName + " " + person.lastName;
})
</script>
自定义复用逻辑
组合式API提供了一种简单的方式来自定义复用逻辑。我们可以将复杂的逻辑封装成一个函数,然后在多个组件中复用这个函数。这个函数可以返回一些响应式的数据,方法,或者其他的组合函数。
如上一节中的counter,我们定义成如下计算逻辑:
typescript
// counter.ts
import { ref, watch } from 'vue'
const count = ref(0);
const changeCount = () => {
count.value++;
}
const doubleCount = ref(0);
watch(() => count, () => {
doubleCount.value = count.value * 2;
});
export function useCounter() {
return {
count,
changeCount,
doubleCount
}
}
// MyComponent.vue
<script setup lang="ts">
import { useCounter } from '../counter';
const { count, changeCount, doubleCount } = useCounter();
</script>
<template>
<button @click="changeCount">count:{{ count }}</button>
<p />
<span>doubleCount:{{ doubleCount }}</span>
</template>
上面代码定义了一个自定义复用逻辑useCounter
,在VUE直接导入使用,代码可读性增强,逻辑更加聚合,代码更易维护。
官方约定,自定义复用逻辑组合函数的命名都以use开头。
生命周期钩子函数
在Vue3中,生命周期钩子函数的使用方式有所变化。我们可以在setup
函数中直接使用它们,而不需要将它们放在created
、mounted
等选项中。这使得我们能够更直观地看到组件的生命周期。
主要有以下钩子函数:
- onBeforeMount(): 在组件被挂载之前调用,此时组件已经完成了响应式状态的设置,但还没有创建 DOM 节点。
- onMounted(): 在组件被挂载之后调用,此时组件已经创建了 DOM 节点,并插入了父容器中。可以在这个钩子中访问或操作 DOM 元素。
- onBeforeUpdate(): 在组件即将因为响应式状态变更而更新其 DOM 树之前调用,可以在这个钩子中访问更新前的 DOM 状态。
- onUpdated(): 在组件因为响应式状态变更而更新其 DOM 树之后调用,可以在这个钩子中访问更新后的 DOM 状态。
- onBeforeUnmount(): 在组件实例被卸载之前调用,此时组件实例依然还保有全部的功能。
- onUnmounted(): 在组件实例被卸载之后调用,此时组件实例已经失去了全部的功能。可以在这个钩子中清理一些副作用,如计时器、事件监听器等。
- onErrorCaptured(): 在捕获了后代组件传递的错误时调用,可以在这个钩子中处理错误或阻止错误继续向上传递。
- onRenderTracked(): 在组件渲染过程中追踪到响应式依赖时调用,仅在开发模式下可用,用于调试响应式系统。
代码示例:
typescript
<script setup lang="ts">
import { onMounted } from 'vue';
onMounted(() => {
console.log("onMounted")
})
</script>
其他
对于Vue2的用户来说,迁移到Vue3可能需要一些时间来适应新的API。但是,一旦你熟悉了组合式API,你会发现它提供了一种更直观、更灵活的方式来组织和复用代码。
在Vue3中,响应式数据的实现原理是使用了ES6的Proxy和Reflect。这使得Vue3能够更精确地追踪依赖,从而提高性能。
关于 OpenTiny
OpenTiny 是一套华为云出品的企业级组件库解决方案,适配 PC 端 / 移动端等多端,涵盖 Vue2 / Vue3 / Angular 多技术栈,拥有主题配置系统 / 中后台模板 / CLI 命令行等效率提升工具,可帮助开发者高效开发 Web 应用。
核心亮点:
跨端跨框架
:使用 Renderless 无渲染组件设计架构,实现了一套代码同时支持 Vue2 / Vue3,PC / Mobile 端,并支持函数级别的逻辑定制和全模板替换,灵活性好、二次开发能力强。组件丰富
:PC 端有80+组件,移动端有30+组件,包含高频组件 Table、Tree、Select 等,内置虚拟滚动,保证大数据场景下的流畅体验,除了业界常见组件之外,我们还提供了一些独有的特色组件,如:Split 面板分割器、IpAddress IP地址输入框、Calendar 日历、Crop 图片裁切等配置式组件
:组件支持模板式和配置式两种使用方式,适合低代码平台,目前团队已经将 OpenTiny 集成到内部的低代码平台,针对低码平台做了大量优化周边生态齐全
:提供了基于 Angular + TypeScript 的 TinyNG 组件库,提供包含 10+ 实用功能、20+ 典型页面的 TinyPro 中后台模板,提供覆盖前端开发全流程的 TinyCLI 工程化工具,提供强大的在线主题配置平台 TinyTheme
联系我们:
- 官方公众号:
OpenTiny
- OpenTiny 官网:opentiny.design/
- OpenTiny 代码仓库:github.com/opentiny/
- Vue 组件库:github.com/opentiny/ti... (欢迎 Star)
- Angluar组件库:github.com/opentiny/ng (欢迎 Star)
- CLI工具:github.com/opentiny/ti... (欢迎 Star)