初探 Vue3 Hooks

3,926 阅读3分钟

Vue3 的时代已来临, 其中推荐使用组合式 Api, 也就是由之前的类编程转换为函数式编程,由 setup 作为组合式 API 的入口点。作为函数式编程 Hooks 是必不可少的

Hooks 钩子

  • Hooks 不是全新的技术,它是一种发开思想,新建文件 src->hooks->useXX.js 或者某模块下->hooks->useXX.js
  • 可以利用 Hook 函数把相关的代码剥离出去,减少代码冗余
  • Hook 函数有个编码习惯有 use 开头 (类似 vue2 中 mixin 的命名方式 $_XX_XX)
  • 这样组件会非常干净,不同的业务拆分到不同页面去写,非常方便利于方法拓展,复用,重构等
  • Hook 函数里面的数据只有返回出去的数据,变动才会就会跟着变动
  • 一个业务在多个组件中使用,两个组件中使用是两份数据
  • 执行两次函数,调用两次其实在内存中创建了两个,两份数据彼此不受影响
  • B 站视频

hooks 函数优点

  • 自定义 hook 的作用类似于 vue2 中的 mixin 技术,使用方便,上手没有难度。
  • 使用 Vue3 的组合 API 封装的可复用切服用,且高内聚低耦合的功能函数。
  • 自定义 Hook 的优势: 很清楚复用功能代码的来源,可塑性高, 更清楚易懂。

示例

这里可以将其封装成一个 hook, 我们约定这些自定义 Hook 以 use 作为前缀,和普通的函数加以区分。

// useCount.ts 实现
import { ref, Ref, computed } from 'vue'
type countResultObj = {
  count: Ref<number>
  increase: (increaseCount?: number) => void
  decrease: (decreaseCount?: number) => void
}
// 返回的类型是countResultObj中的类型
export const useCount = (init = 10): countResultObj => {
  const count = ref(init)
  // 固定加几?increaseCount参数
  const increase = (increaseCount?: number): void => {
    if (typeof increaseCount !== 'undefined') {
      count.value += increaseCount
    } else {
      count.value += 1
    }
  }
  const decrease = (decreaseCount?: number): void => {
    if (typeof decreaseCount !== 'undefined') {
      count.value -= decreaseCount
    } else {
      count.value -= 1
    }
  }
  return {
    count,
    increase,
    decrease
  }
}

接下来看一下在组件中使用 useCount 这个 hook:

<template>
  <p>count: {{ count }}</p>
  <p>倍数: {{ multiple }}</p>
  <div>
    <button @click="increase()">加1</button>
    <button @click="decrease()">减一</button>
  </div>
</template>

<script setup lang="ts">
import useCount from '../hooks/useCount'
const { count, multiple, increase, decrease } = useCount(10)
</script>

Vue2.x 实现,大部分逻辑分散在 data,method,computed 等。如果刚接手项目,实在无法快速将 data 字段和 method 关联起来,那么而 Vue3 的组合式 API 可以很明确的看出,将 count 相关的逻辑聚合在一起, 看起来舒服多了, 而且 useCount 还可以扩展更多的功能(具备可拓展性)。

项目开发完之后,后续介绍功能模块时写开发文档总结,Hooks 的功能模块,帮助大家更高效的编写文档。

hooks 是 mixins 的最优解

程序设计中重要的点引用大于继承

mixins 是 Vue2.x Options API 中常用的代码逻辑抽离手段,在 Vue3.x 中也同样可以使用。 虽然好用,但其仍有一些比较显著的缺点 ,而 Vue3.x 引入的 Composition API 中的自定义 hook 很好的解决了 mixins 带来的一些问题。

mixins 的缺点

  1. 变量来源不明确(隐式传入),不利于阅读,使代码变得难以维护。

    组件里可以引入多个 mixin,并直接隐式调用 mixin 里的变量/方法,这会让我们有时候混乱,这些变量/方法 分别是哪个 mixin 里的?

  2. 多个 mixins 的生命周期会融合到一起运行,但是同名属性、同名方法无法融合,可能会导致冲突。
  3. mixins 和组件可能出现多对多的关系,复杂度较高(即一个组件可以引用多个 mixins,一个 mixins 也可以被多个组件引用)。

注:VUE3 提出的 Composition API 旨在解决这些问题。mixins 的缺点是 Composition API 背后的主要动因之一,Composition API 受到 React Hooks 的启发。