引言
Vue 3 的推出,带来了 Composition API 这一新的特性,它允许开发者以一种更灵活和直观的方式组织代码。Composition API 提供了一种钩子(hooks)的编程风格,这种风格借鉴了 React hooks 的概念,但针对 Vue 的响应式系统进行了优化。本文将探讨如何在 Vue 3 中使用 hooks 编程风格来编写更加模块化、易于维护和复用的组件。
示例
当数据和方法越来越多时,这些不同的数据和方法全部杂糅到一起,这种方式虽然简单直接,但对于大型应用来说,会导致逻辑混乱且难以维护。Vue 3 的 Composition API 则鼓励我们将逻辑拆分成小的、可复用的函数,即“hooks”。这些 hooks 可以独立地管理状态,并且可以组合起来构建复杂的界面逻辑。
什么是hooks?
hook是钩子的意思,看到钩子是不是就想到了钩子函数?hooks就是函数的一种写法。
就是将一些单独功能的js代码抽离出来,放到单独的js文件中,或者说是一些可以复用的公共方法/功能。
hooks 编程风格:数据和方法贴在一起,并且以模块化思想加持,把数据和功能包在一个函数里,并暴露出去。
通俗的理解:
想象一下你在准备一顿丰盛的晚餐,有好几个步骤要完成:洗菜、切菜、烹饪和最后摆盘。如果你把所有这些步骤都写在一张纸上,那张纸可能会变得非常混乱,尤其是在你还要记住每个步骤的时间点以及如何处理意外情况(比如刀子掉了或者火太大了)。
现在,Hooks 编程就像为每个任务创建一个专门的小助手。每个小助手只专注于一个特定的任务,比如“洗菜助手”、“切菜助手”等,并且它们知道什么时候该开始工作(例如,当食材准备好时)。这些助手还可以告诉你它们的状态(例如,“我刚洗完所有的蔬菜”),这样你就知道下一步该做什么了。
自定义hooks的使用规范
命名规范
使用 use 前缀
驼峰命名
语义化
返回值规范
返回对象而不是数组
提供完整的类型定义
保持一致的命名
错误处理
提供错误状态
合理的异常捕获
友好的错误信息
生命周期处理
及时清理副作用
避免内存泄漏
处理组件卸载
hooks实战:完成示例代码
App根组件:
<script setup>
import MosePos from './components/MousePos.vue';
import { ref } from 'vue';
const showMouse = ref(true)
const toggleMouse = () => {
showMouse.value = !showMouse.value
}
</script>
<template>
<div>
<MosePos v-if="showMouse" />
<button @click="toggleMouse">切换显示</button>
</div>
</template>
<style scoped></style>
实例中演示的追踪坐标和sum组件 MousePos.vue:
<template>
<div>
<p>Mouse X: {{ x }}</p>
<p>Mouse Y: {{ y }}</p>
<p>sum: {{ sum }}</p>
<button @click="add">Add</button>
</div>
</template>
<script setup>
import useMouse from '../hooks/useMouse.js'
import useSum from '../hooks/useSum.js';
const { x, y } = useMouse();
const { sum, add } = useSum();
</script>
<style scoped>
</style>
将响应式业务 和 UI 分离开来
让组件更好维护, 复用性高
组件拆分为 UI界面 和 业务逻辑
利用 ES6 的模块化特性,我们可以更好地组织代码结构。通过 import 和 export 语句,可以轻松实现代码的分隔与共享。而函数式编程的思想则有助于我们将业务逻辑从 UI 层面解耦出来,使得组件更加专注于展示内容,而逻辑处理被抽象到单独的函数中。
src目录下创建hooks文件夹,并创建useMouse.js、useSum.js:
useMouse.js:
import { ref, onMounted, onUnmounted } from 'vue';
export default function useMouse() {
const x = ref(0);
const y = ref(0);
function update(event) {
x.value = event.pageX;
y.value = event.pageY;
console.log('我动了')
}
onMounted(() => window.addEventListener('mousemove', update));
onUnmounted(() => window.removeEventListener('mousemove', update));
return { x, y };
}
在这个例子中,useMouse 就像是一个专门用来跟踪鼠标位置的小助手,它自己处理了所有相关的细节,包括监听事件和清理工作。而组件本身只需要关心如何展示这些信息。这种方式使得代码更加模块化、易于维护和测试。
组件销毁,不会主动取消事件监听,事件处理函数无法回收
别忘记在卸载组件时移除监听,防止内存泄漏
import { ref } from "vue";
export default function useSum() {
let sum = ref(0);
function add() {
sum.value += 1;
}
return { sum, add };
}
总结
在 Vue 3 的 Composition API 中,Hooks 编程风格意味着你可以:
分离关注点:把不同的业务逻辑放到独立的函数里,而不是把所有东西都塞进组件选项对象。
复用逻辑:编写一次逻辑,然后可以在多个地方使用,而不需要复制粘贴代码。
更清晰的生命周期管理:通过像 onMounted 和 onUnmounted 这样的钩子来明确地定义何时执行某些操作。
响应式变量与副作用:使用 ref 和 reactive 来创建响应式的变量,并通过 watch 和 watchEffect 来处理副作用,如异步调用或DOM操作。
作者:经常见
链接:https://juejin.cn