当前位置:  首页>> 技术小册>> TypeScript和Vue从入门到精通(三)

10.3 组合式API的应用

在Vue 3中,组合式API(Composition API)的引入是一次重大的架构革新,它提供了一种更为灵活和强大的方式来组织和重用逻辑。与Vue 2中的Options API相比,组合式API允许开发者将组件的逻辑按照功能组织起来,而不是分散在多个选项(如datamethodscomputed等)中。这种方式不仅提高了代码的可读性和可维护性,还使得在大型项目中管理和复用逻辑变得更加容易。本章将深入探讨组合式API的应用,包括其基本概念、核心API的使用、以及如何在实际项目中高效地利用它们。

10.3.1 组合式API基础

1. 引入与设置

组合式API主要通过setup()函数来访问和使用。setup()函数是Vue 3中新增的一个组件选项,它是所有组合式API调用的入口点。在setup()中,你可以定义响应式状态、计算属性、方法以及生命周期钩子等。重要的是,setup()函数在组件被创建之前调用,并且它接收两个参数:propscontext(一个普通JavaScript对象,包含attrsslotsemit等)。

2. 响应式状态

在组合式API中,你可以使用reactiveref来创建响应式状态。reactive用于创建一个响应式的对象,而ref则用于基本数据类型的响应式引用。两者都是Vue 3的响应式系统的一部分,确保当数据变化时,视图能够自动更新。

  1. import { reactive, ref } from 'vue';
  2. export default {
  3. setup() {
  4. const state = reactive({ count: 0 });
  5. const message = ref<string>('Hello Vue 3!');
  6. // 修改状态
  7. function increment() {
  8. state.count++;
  9. }
  10. // 访问响应式引用
  11. function getMessage() {
  12. console.log(message.value);
  13. }
  14. return { state, message, increment, getMessage };
  15. },
  16. };

3. 计算属性和监视器

组合式API提供了computedwatch/watchEffect来分别处理计算属性和侦听器。computed用于声明计算属性,它基于响应式数据自动更新。watchwatchEffect则用于侦听数据变化并执行副作用。

  1. import { computed, watch, watchEffect, ref } from 'vue';
  2. export default {
  3. setup() {
  4. const count = ref(0);
  5. // 计算属性
  6. const doubleCount = computed(() => count.value * 2);
  7. // 立即运行一次,然后侦听count变化
  8. watchEffect(() => {
  9. console.log(`count is: ${count.value}`);
  10. });
  11. // 显式侦听count变化
  12. watch(count, (newVal, oldVal) => {
  13. console.log(`count changed from ${oldVal} to ${newVal}`);
  14. });
  15. return { count, doubleCount };
  16. },
  17. };

10.3.2 组合式API的高级应用

1. 使用setup()与TypeScript

TypeScript与Vue 3的组合式API结合使用时,可以提供类型安全和更丰富的开发体验。通过TypeScript,你可以为响应式状态、计算属性、方法等提供类型注解,从而在开发过程中获得更准确的错误检查和提示。

  1. import { reactive, ref, computed } from 'vue';
  2. export default {
  3. setup() {
  4. const state = reactive<{ count: number; message: string }>({
  5. count: 0,
  6. message: 'Hello TypeScript!',
  7. });
  8. const doubleCount = computed<number>(() => state.count * 2);
  9. function updateMessage(newMessage: string) {
  10. state.message = newMessage;
  11. }
  12. return { state, doubleCount, updateMessage };
  13. },
  14. };

2. 组件逻辑复用

组合式API的一个显著优势是它能够更容易地实现逻辑复用。你可以将可复用的逻辑封装成可重用的函数,然后在多个组件中导入和使用这些函数。这有助于减少代码重复,提高项目的可维护性。

  1. // useCounter.ts
  2. import { ref } from 'vue';
  3. export function useCounter() {
  4. const count = ref(0);
  5. const increment = () => count.value++;
  6. const decrement = () => count.value--;
  7. return { count, increment, decrement };
  8. }
  9. // 组件中使用
  10. import { useCounter } from './useCounter';
  11. export default {
  12. setup() {
  13. const { count, increment, decrement } = useCounter();
  14. return { count, increment, decrement };
  15. },
  16. };

3. 跨组件通信与Provide/Inject

虽然组合式API本身不直接提供跨组件通信的API,但你可以结合provideinject选项来实现。provideinject允许一个祖先组件向其所有子孙后代注入一个依赖,不论组件层次有多深,并在起始组件和注入组件之间建立起响应式连接。

  1. // 祖先组件
  2. import { provide, ref } from 'vue';
  3. export default {
  4. setup() {
  5. const theme = ref('dark');
  6. provide('theme', theme);
  7. return { theme };
  8. },
  9. };
  10. // 子孙组件
  11. import { inject } from 'vue';
  12. export default {
  13. setup() {
  14. const theme = inject<string>('theme')!;
  15. return { theme };
  16. },
  17. };

10.3.3 实战案例分析

假设我们正在开发一个待办事项应用,每个待办事项可以拥有标题、描述和完成状态。我们可以使用组合式API来设计这个组件,使其更加模块化和可维护。

1. 定义待办事项的数据结构

首先,我们定义一个TodoItem接口来规范待办事项的数据结构。

  1. interface TodoItem {
  2. id: number;
  3. title: string;
  4. description: string;
  5. completed: boolean;
  6. }

2. 创建待办事项的响应式状态

然后,在组件的setup()函数中,我们使用reactive来创建一个响应式的待办事项列表。

  1. import { reactive } from 'vue';
  2. export default {
  3. setup() {
  4. const todos = reactive<TodoItem[]>([
  5. { id: 1, title: 'Learn TypeScript', description: 'Understand types and interfaces', completed: false },
  6. // 更多待办事项...
  7. ]);
  8. // 添加待办事项的方法
  9. function addTodo(title: string, description: string) {
  10. const newId = todos.length + 1;
  11. todos.push({ id: newId, title, description, completed: false });
  12. }
  13. // 切换待办事项的完成状态
  14. function toggleCompletion(id: number) {
  15. const todo = todos.find(todo => todo.id === id);
  16. if (todo) {
  17. todo.completed = !todo.completed;
  18. }
  19. }
  20. return { todos, addTodo, toggleCompletion };
  21. },
  22. };

3. 在模板中使用组合式API

最后,在组件的模板中,我们可以遍历todos数组,渲染每个待办事项,并添加按钮来添加新待办事项或切换完成状态。

  1. <template>
  2. <ul>
  3. <li v-for="todo in todos" :key="todo.id">
  4. <input type="checkbox" :checked="todo.completed" @change="toggleCompletion(todo.id)">
  5. {{ todo.title }} - {{ todo.description }}
  6. </li>
  7. </ul>
  8. <button @click="addTodo('New Todo', 'Description here')">Add Todo</button>
  9. </template>

通过上述例子,我们展示了如何在Vue 3中使用组合式API来构建一个简单的待办事项应用。组合式API不仅提高了代码的可读性和可维护性,还使得逻辑复用和跨组件通信变得更加容易。随着你对组合式API的深入理解,你将能够更高效地构建出更复杂、更健壮的Vue应用。


该分类下的相关小册推荐: