一,什么是Hooks
Hooks技术最早是由React团队的Sophie Alpert和Abramov在2018年提出来的,最初是为了解决React类组件中状态逻辑复用的问题而提出来的。在React使用类组件时,为了复用状态逻辑,需要使用高阶组件或者Render Props等方式,这些方式会增加代码的复杂度和维护成本。而Hooks技术是使用特定函数来“钩到”React的state和生命周期等特性的技术。它可以让我们在函数组件中使用state以及其他的React特性,代替传统的类组件或高阶组件等方式。
Vue3中没有直接引入和React Hooks 相同的概念,尽管Vue3引入了一个与Hooks类似的API,称为Composition API,但两者概念略有不同。Composition API旨在提供更好的代码组织和复用逻辑的方式,它是一组API,使得在Vue3 应用程序中使用基于逻辑的组合更方便,并尝试解决使用Options API 时遇到的一些限制和缺陷。
虽然在Vue3的官方文档中并没有提及使用Hooks技术,但是我们在Vue3中的Composition API 中却时刻能看到Hooks的影子,比如Vue3中的onMounted,onUpdated,onUnmounted等都可以看做时Hooks。这些Hooks可以帮助我们在函数组件中访问Vue的生命周期和状态方法。
二,如何自定义Hooks
自定义Hooks是为了处理组件逻辑的一种模式。它可以让我们在不使用组件之间复制粘贴代码的情况下重用状态逻辑。自定义hooks是简单的javaScrpt函数,但是在使用是,我们要遵循两个重要(不成文)的命名约定:①.以use开头。②.可以调用其他的hooks。
三,如何编写自定义Hooks
在src文件夹下新建一个hooks文件夹,用于统一存放程序中用到的hooks代码。
建一个useCounter.js, 做为自定义hook,它使用reactive创建一个响应式的状态对象,并返回一个包含count属性和increment方法的对象
import { reactive,toRefs } from "vue";
export default function useCounter() {
const state=reactive({
count:0
})
function increment() {
state.count++
}
return {
...toRefs(state),
increment
}
}
在组件中引入useCounter,在setup函数中调用
<template>
{{ count }}
<button @click="increment">add</button>
</template>
<script setup lang='ts'>
import { useCounter } from '@/hooks/useCounter.js';
const {count,increment} = useCounter()
</script>
使用自定义Hooks的组件中使用import将我们创建Hooks代码引入,然后调用里面的属性和方法即可
四,在复杂的场景中使用Hooks
在实际应用中,自定义hooks的使用会比我们上面的示例复杂一些,常用的使用场景包括处理网络请求和状态管理。为了更好的进行代码维护,官方也推荐我们尽可能地把状态和逻辑分离到单一的切面中,单独组织出一个hooks文件,存放整个应用或某个模块中可以重用的业务逻辑。
在处理复杂业务逻辑的时候,有时需要使用某个特定的原生事件,例如:scroll,resize等。可以把一些公共的原生事件处理逻辑封装到一个自定义hooks中,并将其于组件的某个特定属性进行绑定。
例:多个页面监听鼠标滚动时的scrollTop值,新建一个useScroll.js
import {ref,onMounted,onUnmounted,} from 'vue'
export default function useScroll() {
const scrollTop=ref(0)
const handleScroll=(e)=>{
scrollTop.value=e.target.documentElement.scrollTop
}
onMounted(() => {
window.addEventListener('scroll', handleScroll)
}),
onUnmounted(() => {
window.removeEventListener('scroll', handleScroll)
})
return {
scrollTop
}
}
需要获取scrollTop值的组件中引入useScroll.js,获取scrollTop并处理相关业务,
<template>
{{ count }}
<button @click="increment">add</button>
<br>
<div>{{ scrollTop }}</div>
</template>
<script setup lang='ts'>
import useCounter from '@/hooks/useCounter.js';
import useScroll from '@/hooks/useScroll.js';
const { scrollTop } = useScroll()
console.log(scrollTop);
const {count,increment} = useCounter()
</script>
<style>
div {
height:500px;
scroll-margin-top:10px;
}
</style>
五,使用Hooks的优点
1,提高组件代码的可读性和可维护性。
2,简化代码逻辑,减少代码复杂度。
3,消除“渲染属性”或“渲染组件”等传统的高阶组件模式的使用。
4,封装逻辑,使得组件可以更好地适应重用。
5,使用Hook,不需要编写类组件,可以更好的使用javaScript的函数式风格,提高代码扩展性。
总结:本人才疏学浅,水平有限,请大家多多包涵和指点。多谢🤝🫡 👍。 加油✊🫶