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 的缺点
- 变量来源不明确(隐式传入),不利于阅读,使代码变得难以维护。
组件里可以引入多个 mixin,并直接隐式调用 mixin 里的变量/方法,这会让我们有时候混乱,这些变量/方法 分别是哪个 mixin 里的?
- 多个 mixins 的生命周期会融合到一起运行,但是同名属性、同名方法无法融合,可能会导致冲突。
- mixins 和组件可能出现多对多的关系,复杂度较高(即一个组件可以引用多个 mixins,一个 mixins 也可以被多个组件引用)。
注:VUE3 提出的 Composition API 旨在解决这些问题。mixins 的缺点是 Composition API 背后的主要动因之一,Composition API 受到 React Hooks 的启发。