学习笔记-Vue3中Hook函数

什么是Hook函数
Hook翻译过来是钩子的意思,其本质上是一组可复用的函数。简单理解来说,你能够在不同的组件中,实现相同的代码逻辑,以达到代码复用、提高维护性的效果。那为何叫’钩子’呢,我的理解是:

它可以通过特定的函数将逻辑 “钩入” 组件中,使得开发者能够更灵活地构建和管理组件的功能从而提高代码的可读性以及可维护性等

细则:
看完上面的概念,可能还是一头浆糊,这不就是普普通通封装了一个函数然后给我们调用嘛,跟我们平时的函数有啥区别?是,这也是我在学习过程中很疑惑的点,来看看下面的解释吧!
在开发过程中,我们经常会发现一些可重复利用的代码块,于是我们将其封装成函数以供调用。这类函数包括工具函数,但又不止工具函数,因为我们可能也会封装一些重复的业务逻辑。但在以往,在前端原生开发中,我们所封装的函数,大多数是"无状态"的,不能够建立数据与视图之间的联系。
那何为"有状态"的函数呢?这里的"有状态",实际上是指是否含有响应式变量。我们知道,基于MVC架构的React框架和基于MVVM的Vue框架都引入了"状态"这一概念。状态是特殊的JavaScript变量,它的变化能够引起视图的变化。在这类框架中,如果一个变量的变化不会引起视图变化,则为普通变量,如果一个变量已经被框架注册为状态,那么这个变量的变化就会引起视图变化,我们称之为响应式变量。
总结即:如果一个函数包含了响应式变量,那么它就是一个Hook函数。
Hook实现原理
看完上面的解释,我想你应该也能有所领悟,上面提到,所谓Hook函数是指包含了响应式变量,能够让组件实现代码复用的函数。
那在Vue3中,Hooks是基于Composition API实现的其实也不难理解,因为它需要基于响应式变量嘛!
Hooks通过Vue3中setup函数来使用的,setup函数是Vue3组件中的一个新的生命周期函数,它在组件实例被创建之前调用,并且接收两个参数:props和context。在setup函数中,我们可以定义和返回组件中需要使用的响应式数据、方法、计算属性等,而这些都可以通过Hooks来实现。
Hook简单实现
知道了它是怎么个事?那我们怎么用呢!来和我一起探讨吧!
因为本篇文章更多的是想让大家明白hook函数,所以我们这里就举一个特别简单的例子!
业务需求:追踪鼠标位置
在一个夜黑风高的晚上,卷圣优哉游哉地喝着它的咖啡☕,此时它的后端小老弟给它发来信息,说,“大哥!不好了!这老板又改需求了!🤯说需要渲染出用户鼠标的实时位置,而且几乎每个页面都要!!你可能需要加一下班啊!”这时,可能普通程序员已经慌了,但作为一个资深大佬,我们已经很有经验了!
卷圣心想:我就简单地写个hook函数去追踪鼠标位置,然后再到不同视图组件里面去调用,再渲染一下不就成了…,卷圣回复说好的,明白了。
业务实现
没用hook前:

<script setup>
import { ref, onMounted, onUnmounted } from 'vue'const x = ref(0)
const y = ref(0)function update(event) {x.value = event.pageXy.value = event.pageY
}onMounted(() => window.addEventListener('mousemove', update))
onUnmounted(() => window.removeEventListener('mousemove', update))
</script><template>Mouse position is at: {{ x }}, {{ y }}</template>

这时,如果多个页面都同时需要的话,你复制这段代码跑来跑去,而且,你要知道的是,每个页面中的onMounted跟onUnmounted都不一定是空的,并且,变量的命名上,都有可能出现重复的情况发生。这在我们后期维护起来,是非常不方便的!那我们来看看帅气的hook方法吧!
用hook后:
主页面

<script setup>
import { useMouse } from './mouse.js'const { x, y } = useMouse()
</script><template>Mouse position is at: {{ x }}, {{ y }}</template>

在同一目录下新建mouse.js文件,在文件内写入以下内容

// mouse.js
import { ref, onMounted, onUnmounted } from 'vue'// 按照惯例,组合式函数名以“use”开头
export function useMouse() {// 被组合式函数封装和管理的状态const x = ref(0)const y = ref(0)// 组合式函数可以随时更改其状态。function update(event) {x.value = event.pageXy.value = event.pageY}// 一个组合式函数也可以挂靠在所属组件的生命周期上// 来启动和卸载副作用onMounted(() => window.addEventListener('mousemove', update))onUnmounted(() => window.removeEventListener('mousemove', update))// 通过返回值暴露所管理的状态return { x, y }
}

在这里,我们封装了一个hook库来实现鼠标追踪,若有其他组件需要使用,我们只需要将其引入,并使用变量即可,并不需要过多考虑变量重名,生命周期钩子代码过多问题!!当然,这里的逻辑比较清晰,当逻辑比较复杂的时候,你可能更能感受到它的强大!
这里介绍一个VueUse 库,它是Vue3生态中最受欢迎的第三方Hooks库之一,这里封装了很多hook函数,或许你能在其中找到或学习更为复杂的hook函数调用!
Hook的使用场景

逻辑复用:当多个组件需要共享相同的逻辑时,我们可以将这些逻辑封装成一个Hook,然后在需要的组件中导入并使用它。这样可以避免代码重复,提高代码的复用性。

逻辑拆分:对于复杂的组件,我们可以使用Hooks将组件的逻辑拆分成多个独立的函数,每个函数负责处理一部分逻辑。这样可以使组件的代码更加清晰、易于维护。

副作用管理:Hooks中的函数可以访问组件的响应式数据,并且可以在组件的生命周期中执行副作用操作(如定时器、事件监听等)。通过使用Hooks,我们可以更好地管理这些副作用操作,确保它们在组件卸载时得到正确的清理。

Vue3中的Hook与Vue2中的mixn
🐼可能你也感受到了,它有点像我们以前 Vue2 学习的mixn!
🐼我们都知道 Vue3 引入 Composition API的写法,当我们引入一个 hooks 函数的时候其实就像在 Vue2 中使用一个 mixin 一样,hooks 函数中的ref,reactive就相当于 mixin 中的data,同时 hooks 还可以引入一些生命周期函数,watch 等在 mixin 中都有体现。下面简单展示一下 mixin 的写法,不过多讲解
定义

export const mixins = {data() {return {msg: "",};},computed: {},created() {console.log("我是mixin中的created生命周期函数");},mounted() {console.log("我是mixin中的mounted生命周期函数");},methods: {clickMe() {console.log("我是mixin中的点击事件");},},
};

组件中使用

export default {name: "App",mixins: [mixins],components: {},created() {console.log("组件调用minxi数据", this.msg);},mounted() {console.log("我是组件的mounted生命周期函数");},
};

用过 vue2 的 mixin 的都知道,它虽然可以封装一些逻辑,但是它同时也带来了一些问题。
比如你引入多个 mixin 它们的 data,methods 命名可能会冲突,当 mixin 多了可能会出现维护性问题,另外 mixin 不是一个函数,因此不能传递参数来改变它的逻辑,具有一定的局限性等,但这些问题到了 vue3 的 hooks 中则迎刃而解
Hook优缺点
优点:

提高了代码的复用性和可维护性。
使组件的逻辑更加清晰、易于理解。
更好地管理组件的副作用操作。

缺点:

学习曲线较陡峭,需要熟悉新的编程模式和思维方式。
对于小型项目或简单组件,使用Hooks可能过于复杂。
在Vue生态中,第三方Hooks的质量和兼容性可能存在差异。

Hooks书写规范

命名规范:自定义Hooks应该以“use”为前缀,以区分其他函数和变量。例如:useUserInfo、useMousePosition等。同时,命名应清晰明了,准确描述Hooks的功能。
参数与返回值:自定义Hooks应该接收明确的参数,并返回需要在组件中使用的响应式数据、方法、计算属性等。返回的对象应该具有清晰的属性名和结构。
副作用管理:如果自定义Hooks包含副作用操作(如定时器、事件监听等),应确保在组件卸载时正确清理这些副作用。可以使用onMounted、onUnmounted等生命周期钩子来管理副作用的添加和移除。
文档注释:为自定义Hooks编写清晰的文档注释是非常重要的,说明其用途、参数、返回值和使用示例。这将有助于其他开发者理解和使用你的自定义Hooks。
类型定义(如果使用TypeScript):为自定义Hooks提供类型定义可以确保更好的类型安全性和编辑器支持。使用TypeScript的泛型功能可以增加Hooks的灵活性和可复用性。
测试:为自定义Hooks编写单元测试是确保其正确性和稳定性的重要手段。测试应该覆盖各种使用场景和边界情况。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/10767.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

商业数据分析--时间序列图及趋势分析

绘制时间序列图,并指出存在什么样的状态如上两图: 可见状态:从时间序列图可以看出,这些数据存在明显的季节性波动,每年的第4季度值都最高,而第2季度值最低。同时也存在一些下降的趋势。 通过引进虚拟变量,建立多元线性回归模型。答: 通过引入虚拟变量,我们可以建立如下的…

Oracle数据库之多表查询、层次查询(五)

目录 前言 Oracle 的连接条件的类型 多表查询 1. 使用JOIN关键字 2. 使用WHERE子句进行多表查询 3. 子查询 4. EXISTS关键字 5. 集合运算 6. 注意事项&#xff1a; 层次查询 前言 Oracle 的连接条件的类型 等值连接不等值连接外连接自连接 多表查询 在Oracle数据…

商场学习之微服务

前言 寒假前在新电脑上配置了java环境&#xff0c;maven仓库&#xff0c;node,js&#xff0c;navicat&#xff0c;MySQL&#xff0c;linux&#xff0c;vmware等环境&#xff0c;创建了6个mysql数据库&#xff0c;77张表。 如此多的表&#xff0c;字段&#xff0c;去手写基础…

Web入门——三栏布局页面

前置知识 内外边距 内边距(padding)&#xff1a; padding是元素边框与其内容之间的空间。也就是说&#xff0c;如果你给一个元素设置了内边距&#xff0c;这个空间会作为元素内容与元素边框之间的缓冲区域。设置内边距会使元素本身变大。例如padding:10px就创建了10像素的空间…

Qt之QMqtt 发送图片数据

简述 MQTT(消息队列遥测传输)是ISO标准下基于发布/订阅范式的消息协议;它工作在TCP/IP协议族上,是为硬件性能低下的远程设备以及网络状况糟糕的情况下而设计的发布/订阅型消息协议,为此,它需要一个消息中间件; MQTT是一个基于客户端-服务器的消息发布/订阅传输协议;MQT…

Ubuntu设置中午输入法

本篇博客将指导您如何在Ubuntu系统中设置中文输入法&#xff0c;让您能够轻松地进行中文输入。 准备工作 在开始之前&#xff0c;请确保您的系统已经更新到最新版本。这可以通过以下命令来完成&#xff1a; sudo apt update && sudo apt upgrade这将帮助确保所有的软…

Docker in Docker(DinD)原理与实战

&#x1f407;明明跟你说过&#xff1a;个人主页 &#x1f3c5;个人专栏&#xff1a;《Docker幻想曲&#xff1a;从零开始&#xff0c;征服容器宇宙》 &#x1f3c5; &#x1f516;行路有良友&#xff0c;便是天堂&#x1f516; 目录 一、引言 1、Docker简介 2、Docker …

使用 AI Assistant for Observability 和组织的运行手册增强 SRE 故障排除

作者&#xff1a;Almudena Sanz Oliv, Katrin Freihofner, Tom Grabowski 通过本指南&#xff0c;你的 SRE 团队可以实现增强的警报修复和事件管理。 可观测性 AI 助手可帮助用户使用自然语言界面探索和分析可观测性数据&#xff0c;利用自动函数调用来请求、分析和可视化数据…

Harmony 添加library依赖库步骤

在Harmony添加library依赖库步骤如下&#xff1a; 1、在library中定义名字 在library中的oh-package.json5中定义library对外的名字是什么&#xff1a;格式是 “name”:“ohos/名字” {"name": "ohos/library_name" //名字 }2、在项目目录build-profi…

windows系统安装Ubuntu子系统

安装前先在 控制面板 中打开 程序与功能选项 &#xff0c;点击 启用或关闭Windows功能&#xff1a; 勾选 适用于 Linux的Windows子系统 和 虚拟机平台 、 Hyper-v 。 重启电脑后再 Microsoft Store Windows应用商店 中下载合适的Ubuntu版本。 运行Ubuntu程序&#xff0c;如出现…

【实战】算法思路总结

面试过程中&#xff0c;总是被拷打&#xff0c;信心都要没了。但是也慢慢摸索出一些思路&#xff0c;希望对大家有帮助。 &#xff08;需要多用一下ACM模式&#xff0c;力扣模式提供好了模板&#xff0c;自己在IDEA里面写的话&#xff0c;还是会有些陌生&#xff09; 0、基本…

僵尸进程111

Linux 系统中的进程可能处于如下状态中的一种&#xff1a; D 不可中断的休眠 I 空闲 R 运行中 S 休眠 T 被调度信号终止 t 被调试器终止 Z 僵尸状态 Interruptible Sleep&#xff0c;可中断睡眠&#xff0c;在 ps 命令中显示 S。处在这种睡眠状态的进程是可以通过给它…

OC中Block为什么不能为nil

在 Objective-C 中&#xff0c;向 nil 对象发送消息是完全有效的&#xff0c;这是因为 Objective-C 运行时对 nil 消息发送进行了特别的处理。当你向 nil 对象发送消息时&#xff0c;消息会被静默地忽略&#xff0c;不执行任何操作&#xff0c;也不会返回任何值&#xff08;或者…

Unity Editor 找物体助手

找啊找朋友~ &#x1f371;功能介绍&#x1f959;使用方法 &#x1f371;功能介绍 &#x1f4a1;输入相关字符串&#xff0c;它会帮你找到名称中带有该字符串的所有物体&#xff0c;还会找包含该字符串的Text、TextMeshProUGUI。 &#x1f959;使用方法 &#x1f4a1;导入插…

小学拼音弄一下

import re from xpinyin import Pinyindef remove_middle_characters(text):# 仅保留汉字chinese_chars re.findall(r[\u4e00-\u9fff], text)cleaned_text .join(chinese_chars)# 如果字符数为偶数&#xff0c;则在中间添加空格if len(cleaned_text) % 2 0:middle_index le…

【北京迅为】《iTOP-3588从零搭建ubuntu环境手册》-第5章 安装SSH

RK3588是一款低功耗、高性能的处理器&#xff0c;适用于基于arm的PC和Edge计算设备、个人移动互联网设备等数字多媒体应用&#xff0c;RK3588支持8K视频编解码&#xff0c;内置GPU可以完全兼容OpenGLES 1.1、2.0和3.2。RK3588引入了新一代完全基于硬件的最大4800万像素ISP&…

从0开始学python(七)

目录 前言 1 break、continue和pass函数 1.1 break 1.2 continue 1.3 pass 2、序列的索引及切片操作 2.1字符串的索引和切片 2.1.1 字符串索引 2.1.2 字符串切片 总结 前言 上一篇文章我们介绍了python中的循环结构&#xff0c;包括for和while的使用。本章接着往下讲。…

腾讯云服务器之ssh远程连接登录及转发映射端口实现内网穿透(实现服务器访问本地电脑端口)

目录 一、创建密钥绑定实例二、设置私钥权限三、ssh远程连接到服务器四、修改root密码五、端口转发&#xff08;实现服务器访问本地电脑的端口&#xff09; 一、创建密钥绑定实例 创建密钥会自动下载一个私钥&#xff0c;把这个私钥复制到c盘 二、设置私钥权限 1、删除所有用户…

免费剪辑的素材资源网站,超高清、可商用、不限速、无版权,迅速有效的解决您的视频剪辑难题!

在数字媒体时代&#xff0c;高质量的剪辑素材已成为视频制作的核心资源。下面为您推荐的优质视频剪辑素材网站&#xff0c;都提供超高清、无限速、无版权、可商用的素材&#xff0c;这些网站将大大提升您的视频制作效率和质量 01. 蛙学府 实用性&#xff1a;★★★★☆ 丰富性&…

您真的会高效使用 Mac 吗?

文章目录 屏幕的保养快捷键预览修改文件名查看文件属性搜索编辑复制&#xff0c;粘贴&#xff0c;剪切&#xff0c;撤销删除 跳转窗口屏幕截图声音Dock强制退出查字典神奇的Option键鼠标与触控板切换桌面与应用程序打开通知中心打开Mission Control 安装与卸载Mac应用程序压缩和…