vue3 hooks思考

Daotin 于 2024-02-01 发布 编辑

什么是基于Composition API 的 Hooks?

首先,让我们从基础开始谈起。

Vue 3 引入了一个新的 API:Composition API。这个 API 提供了一种新的方式来组织和复用组件的逻辑。在 Vue 2 中,我们主要使用 Options API,它是基于属性(例如 datamethodscomputedwatch 等)来组织组件逻辑的。而在 Vue 3 的 Composition API 中,我们使用 setup() 函数来组合各种逻辑。

Hooks 在这里是一个非正式的术语,它来源于 React 的“Hooks”概念。Hooks 是一种可以让你在不使用 class 的情况下使用 React 的功能(如 state、effects 和 context)的功能。在 Vue 的背景下,我们可以理解为:基于 Composition API 的函数,这些函数封装了某一特定的逻辑功能,并且可以在多个组件中重用。

让我们通过一个简单的例子来理解 Vue 3 中的“Hooks”。

假设你想在多个组件中使用窗口的宽度。每次窗口大小改变时,你都想更新这个宽度值。在 Vue 3 中,你可以创建一个基于 Composition API 的 hook 来实现这个逻辑:

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

function useWindowWidth() {
  const width = ref(window.innerWidth);

  const updateWidth = () => {
    width.value = window.innerWidth;
  };

  onMounted(() => {
    window.addEventListener('resize', updateWidth);
  });

  onUnmounted(() => {
    window.removeEventListener('resize', updateWidth);
  });

  return { width };
}

export default useWindowWidth;

现在,任何组件都可以使用 useWindowWidth hook 来获取和响应窗口的宽度:

import useWindowWidth from './path-to-useWindowWidth';

export default {
  setup() {
    const { width } = useWindowWidth();

    return { width };
  }
}

这样,useWindowWidth 就是一个基于 Composition API 的 hook,它封装了窗口宽度的逻辑并使其可以在多个组件中重用。

utils vs hooks

有时候我会将一些重复的代码逻辑封装在通用的utils/index.js文件中,所有我不清楚什么时候应该封装hook,什么时候应该封装utils?

这是一个非常好的问题。将代码逻辑封装在 utils 和封装为 hook 都是为了实现代码重用和整洁,但它们各自适用于不同的场景。以下是一些建议和区分它们的方法:

  1. 与 Vue 组件的交互
    • Hook:如果你的代码逻辑与 Vue 的生命周期、响应性系统或其他 Vue 特性(如 ref, reactive, watch, computed 等)有直接的交互,那么使用 hook 是合适的。例如,你希望在组件挂载时请求数据,并在响应中跟踪数据,那么你应该使用 hook。
    • Utils:如果你的代码逻辑是纯粹的 JavaScript,不涉及 Vue 或其生命周期等特性,那么最好将其放在 utils 中。例如,日期格式化、数据验证等。
  2. 代码的复杂性
    • Hook:如果你的代码有多个与 Vue 相关的部分,或者它涉及到多个反应性的部分,并且这些部分之间有互动,那么将其封装为 hook 可能更合适。
    • Utils:简单的、无状态的函数,或者一些常量、配置,都是适合放在 utils 中的。
  3. 是否需要状态
    • Hook:如果你的逻辑需要维护和跟踪状态,尤其是 Vue 的响应性状态(如 refreactive),那么你应该使用 hook。
    • Utils:不维护状态的纯函数,如转换函数、辅助函数等,更适合放在 utils 中。
  4. 通用性
    • Hook:特定于 Vue 的,可能会在不同的 Vue 组件中使用的逻辑。
    • Utils:与框架无关的、纯 JavaScript 逻辑,可能会在 Vue 之外的上下文中使用。

综上所述,决定使用 hook 还是 utils 主要取决于代码的性质和你希望达到的目标。需要记住的是,无论选择哪种方法,目标都是使代码更加整洁、可维护、可重用。在实际开发过程中,随着经验的积累,你会更加自然地做出这些决策。