vue3 Composable介绍

好的,我们来深入探讨一下 Vue 3 的 Composable

1. 什么是 Composable?

Composable 是 Vue 3 中一个核心的概念和功能,它是可复用的、有状态的逻辑块,用于封装和提取组件中的重复逻辑,让代码更清晰、更易于维护。

你可以把它理解为:专门用来存放 "可以被多个组件复用的业务逻辑" 的函数

2. 为什么需要 Composable?

在 Vue 2 中,我们通常使用 Mixins 来复用逻辑。但 Mixins 存在一些问题:

  • 命名冲突:多个 Mixin 可能会定义相同名称的数据或方法,导致覆盖。
  • 来源不清晰:当一个组件使用了多个 Mixin 后,很难追踪某个数据或方法到底来自哪个 Mixin。
  • 逻辑耦合度高:Mixins 和组件之间是隐式依赖关系,不易于单独测试和维护。

而 Composable 则完美解决了这些问题:

  • 明确的依赖关系:通过函数调用和返回值来显式地传入和获取数据,来源清晰。
  • 无命名冲突:返回的内容通过解构赋值的方式被组件接收,组件可以自己决定命名。
  • 更好的类型推断:对于 TypeScript 非常友好,能提供完整的类型提示。
  • 更易于测试:Composable 本身就是一个函数,可以独立进行单元测试。

3. 如何创建一个 Composable?

创建一个 Composable 非常简单,它就是一个use 开头的函数 (这是一个约定,便于识别),在函数内部可以使用 Vue 的响应式 API(如 ref, reactive, computed, watch 等),并返回需要暴露给组件使用的状态和方法。

示例:创建一个处理计数器逻辑的 Composable

运行

javascript 复制代码
// src/composables/useCounter.js

import { ref, computed, onMounted } from 'vue';

// 定义一个 Composable 函数,通常以 use 开头
export function useCounter(initialValue = 0) {
  // 1. 定义响应式状态
  const count = ref(initialValue);

  // 2. 定义基于状态的计算属性
  const doubleCount = computed(() => count.value * 2);

  // 3. 定义修改状态的方法
  const increment = () => {
    count.value++;
  };

  const decrement = () => {
    count.value--;
  };

  const reset = () => {
    count.value = initialValue;
  };

  // 4. 可以使用生命周期钩子
  onMounted(() => {
    console.log(`计数器已初始化,初始值为: ${count.value}`);
  });

  // 5. 返回需要暴露给组件的内容
  return {
    count,
    doubleCount,
    increment,
    decrement,
    reset
  };
}

4. 如何在组件中使用 Composable?

在组件中,你只需要 导入并调用 这个 Composable 函数,然后通过解构赋值的方式获取其返回的状态和方法即可。

示例:在组件中使用 useCounter

vue 复制代码
<!-- src/components/CounterDisplay.vue -->
<template>
  <div>
    <p>当前计数: {{ count }}</p>
    <p>计数的两倍: {{ doubleCount }}</p>
    <button @click="increment">+1</button>
    <button @click="decrement">-1</button>
    <button @click="reset">重置</button>
  </div>
</template>

<script setup>
import { useCounter } from '@/composables/useCounter';

// 调用 Composable 函数
// 可以传入初始值,如 useCounter(10)
// 通过解构赋值获取返回的状态和方法
const { count, doubleCount, increment, decrement, reset } = useCounter();
</script>

关键点

  • 每次调用 useCounter(),都会创建一个全新的、独立的 状态实例。这意味着如果两个组件都使用了 useCounter,它们的状态是完全隔离的,互不影响。
  • 组件可以根据需要,只解构自己需要的部分。

5. Composable 的最佳实践

  1. 命名规范

    • Composable 函数名必须以 use 开头 ,例如 useCounter, useUser, useCart
    • 文件名通常与函数名一致,例如 useCounter.js
  2. 单一职责原则

    • 一个 Composable 应该只负责一个特定的功能或逻辑。如果一个 Composable 变得过于庞大和复杂,应该考虑将其拆分成多个更小的、职责更单一的 Composable。
  3. 组合与嵌套

    • Composable 可以相互调用。这是一个非常强大的特性,允许你构建复杂的逻辑。

    • 例如,一个 useCart Composable 内部可以调用 useUser Composable 来获取当前用户信息,以便计算购物车商品的会员价格。

    运行

    javascript 复制代码
    // src/composables/useCart.js
    import { useUser } from './useUser';
    
    export function useCart() {
      const { user } = useUser(); // 调用另一个 Composable
    
      // ... 购物车相关逻辑,可以使用 user 的信息
      const cartItems = ref([]);
      
      const calculateDiscountPrice = (item) => {
        if (user.value?.isVIP) {
          return item.price * 0.9; // VIP 9 折
        }
        return item.price;
      };
    
      // ...
      return { cartItems, calculateDiscountPrice };
    }
  4. 避免在 Composable 中访问组件实例

    • 理想情况下,Composable 应该是纯逻辑 的封装,不应该直接依赖于 Vue 组件实例 (this)。
    • 如果确实需要使用组件实例的属性(如 $route, $store),应该通过参数的形式从组件中传递进来,或者使用 Vue 提供的 getCurrentInstance() 函数(但这会降低 Composable 的通用性,应谨慎使用)。

总结

Composable 是 Vue 3 中替代 Mixins更优、更现代的逻辑复用方案。

  • 它通过函数 的形式封装逻辑,通过返回值暴露状态和方法。
  • 它实现了逻辑的复用和隔离,让组件代码更简洁、更清晰。
  • 它遵循明确的依赖关系单一职责原则,极大地提升了代码的可维护性和可测试性。
  • 在 Vue 3 项目中,任何可复用的逻辑都应该被提取为 Composable
相关推荐
少年姜太公2 小时前
什么?还不知道git cherry pick?
前端·javascript·git
白兰地空瓶4 小时前
🏒 前端 AI 应用实战:用 Vue3 + Coze,把宠物一键变成冰球运动员!
前端·vue.js·coze
Liu.7745 小时前
vue3使用vue3-print-nb打印
前端·javascript·vue.js
松涛和鸣5 小时前
Linux Makefile : From Basic Syntax to Multi-File Project Compilation
linux·运维·服务器·前端·windows·哈希算法
dly_blog6 小时前
Vue 逻辑复用的多种方案对比!
前端·javascript·vue.js
万少6 小时前
HarmonyOS6 接入分享,原来也是三分钟的事情
前端·harmonyos
烛阴6 小时前
C# 正则表达式:量词与锚点——从“.*”到精确匹配
前端·正则表达式·c#
wyzqhhhh6 小时前
京东啊啊啊啊啊
开发语言·前端·javascript
JIngJaneIL6 小时前
基于java+ vue助农电商系统(源码+数据库+文档)
java·开发语言·前端·数据库·vue.js·spring boot·后端
想学后端的前端工程师7 小时前
【Java集合框架深度解析:从入门到精通-后端技术栈】
前端·javascript·vue.js