hooks复杂前端业务解题之道

news2024/11/17 22:40:59

hooks 大势所趋

2019年年初,react 在 16.8.x 版本正式具备了 hooks 能力,同年6月;尤雨溪在 vue/github-issues 里提出了关于 vue3 Component API 的提案(vue hooks的基础)。在Vue3的组合式API出现后,github的一系列基于hooks的项目也是异常火爆,比较突出的是VueUse(16K stars)和 ahooks(12K stars)。由此可以预见hooks将成为业界主流,并深受广大前端程序员喜爱。
什么是hooks?
“hooks” 直译是 “钩子”,指系统运行到某一时期时,会调用被注册到该时机的回调函数。在前端提到钩子可能会跟组件的生命周期函数联系起来,但是现在明显已经给hooks赋予了新的含义。在Vue中hooks的定义为:在 vue 组合式API里,以 “use” 作为开头的,一系列提供了组件复用、状态管理等开发能力的方法。

我们为什么需要hooks?

  • 1.hooks对比于Vue2的mixin,解决了mixin的难以追朔的方法和属性问题
    mixin例子 数据来源无法追朔
export default {  
  mixins: [ a, b, c, d, e, f, g ]
    mounted() {
    console.log(this.name) //  this.name 来自于谁?
  }
}

hooks例子 数据方法来源清晰可见

<script setup lang="ts">
const { name, setName } = useName()
</script>
- 2.解决了mixin很难在一个页面重复使用(实例化多次)
mixin实现多实例繁琐且代码不易读
// 动态生成mixin
function genNameMixin(key, funcKey) {
  return {
    data() {
      return {
        [key]: genRandomName()
      }
    },
    methods: {
      [funcKey]: function(v) {
        this.[key] = v
      } 
    }
  }
}

export default {
  mixins: [
    genNameMixin('firstName', 'setFirstName'),
    genNameMixin('lastName', 'setLastName'),
  ]
}

hooks 实现多实例 简单明了

  • 3.hooks+组合式API优雅地实现代码组织
    在这里插入图片描述

假设把左图中分散在各处的data、mounted、methods,通过hooks按照业务组合在一起(如右图,也就是hooks和组合式API的完美结合),形成”高内聚低耦合“的代码结构,随之而来的则是代码复用率变高、效率提升、可阅读性变强、bug变少。

Vue3中如何使用hooks

  • 命名规范和指导思想
    • 约定1: 一般任何以 「use」 开头并紧跟着一个大写字母的函数就是一个 Hook
    • 约定2:一般只在最顶层使用 Hook,而不要在循环,条件或嵌套函数中调用 Hook
  • 下面是一个简单的hooks例子,下面将用这个例子进行延展
    定义了一个响应式数据name和修改name的函数setName
import { ref } from 'vue'

export default function useName() {
  const name = ref('张三')
  const setName = (val: string) => {
    name.value = val
  }
  return { name, setName }
}
  • 疑问1:hooks函数返回数组行不行?
import { ref } from 'vue'

export default function useName() {
  const name = ref('张三')
  const setName = (val: string) => {
    name.value = val
  }
  return [ name, setName ] // 返回数组
}

答:hooks返回数组当然可以,要分情况,如果hooks在一个页面内需要重复使用(也可以理解为实例化多次)则返回数组更为合适,因为我们更灵活的使用别名,demo如下:

// 使用useName
import useName from './useName'

const [name,setName] = useName()
const [firstName,setFirstName] = useName()
const [secondName,setSecondName] = useName()
反之,返回对象的hooks多实例情况如下,当然除了写法更加麻烦没其他的区别。
// 使用useName
import useName from './useName'

const {name,setName} = useName()
const {name:firstName,setName:setFirstName} = useName()
const {name:secondName,setName:setSecondName} = useName()
  • 疑问2:hooks 跟普通object写法有何区别?如下

用对象模拟hooks函数

import { ref } from 'vue'

export const useName = {
  name: ref('张三'),
  setName: (val: string) => {
    useObj.name.value = val
  }
}

答:粗略看区别不大,都能定义响应式数据,也都返回对象{name,setName}。但本质上是有区别的,该写法无法实现多实例需求,也就是说它是单例的,两个组件同时引用name数据,一个修改了则全部修改(这是区别,不是弊端,有数据/状态共享需求可以使用该方法)。

  • 疑问3: hooks是否可以使用全部组合式API?比如onUnmounted
    答:这个官方案例已经给答案了,全部组合式API都可以使用包括onUnmounted,在组件销毁时也会触发
<script setup>
import { ref, onMounted, onUnmounted } from 'vue'

const x = ref(0)
const y = ref(0)

function update(event) {
  x.value = event.pageX
  y.value = event.pageY
}

onMounted(() => window.addEventListener('mousemove', update))
onUnmounted(() => window.removeEventListener('mousemove', update))
</script>

<template>Mouse position is at: {{ x }}, {{ y }}</template>
  • 疑问4:hooks里写业务行不行?即使它不被复用,单纯用它解耦
    答:这个问题仁者见仁智者见智,作者认为使用hooks不用有太多思想包袱,如果需求是高复用工具函数,封装成hooks自然无可厚非,但是单纯用它处理业务闭环或处理业务逻辑拆分也是没问题的,而且这也是hooks的主要用途没有之一,它是彻底告别”屎山“业务代码的利器。

  • 疑问5:用hooks做数据/状态共享是否可行?
    答:肯定是不行的,上面问题提到hooks在调用时会生成新的实例,调用hooks返回的状态/数据内存地址是不同的,因此无法做到单例和数据共享。

最后;如果您有更多关于hooks的疑问,欢迎留言交流

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

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

相关文章

session反序列化+SoapClientSSRF+CRLF

文章目录 session反序列化SoapClientSSRFCRLF前言bestphps revengecall_user_func()方法的特性SSRFCRLF组合拳session反序列化 解题步骤总结 session反序列化SoapClientSSRFCRLF 前言 从一道题分析通过session反序列化出发SoapClientSSRF利用CRLF解题 bestphp’s revenge 首…

计算机毕设 深度学习人体语义分割在弹幕防遮挡上的实现 - python

文章目录 1 课题背景2 技术原理和方法2.1基本原理2.2 技术选型和方法 3 实例分割4 实现效果5 最后 # 1 前言 &#x1f6a9; 深度学习人体语义分割在弹幕防遮挡上的应用 &#x1f947;学长这里给一个题目综合评分(每项满分5分) 难度系数&#xff1a;3分工作量&#xff1a;3分…

ChatGPT在教育领域的应用:改变学习方式的前沿技术

&#x1f337;&#x1f341; 博主 libin9iOak带您 Go to New World.✨&#x1f341; &#x1f984; 个人主页——libin9iOak的博客&#x1f390; &#x1f433; 《面试题大全》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33…

Flutter Add to App 问题记录

前一阵应用中接入了Flutter&#xff0c;使用的是官方的Multiple FlutterEngine管理方案&#xff0c;目前线上运行良好&#xff0c;这里整理一下遇到的问题。 将 Flutter 集成到现有应用整体来说没有什么问题&#xff0c;按照文档的说明结合demo操作就行。接入后多语言&#xf…

【应用层】Http协议总结

文章目录 一、续->Http协议的学习 1.http请求中的get方法和post方法 2.http的状态码 3.http的报头 4.长链接 5.cookie&#xff08;会话保持&#xff09;总结 继续上一篇的内容&#xff1a; 上一篇的最后我们讲到了web根目录&#xff0c;知道…

Git的.gitignore文件、标签管理以及给命令起别名

文章目录 1. 前言2. .gitignore文件3. 标签管理4. 给命令起别名 1. 前言 本文主要讲解Git中容易被忽略但比较重要一些知识:.gitignore文件、标签管理以及给命令起别名. 2. .gitignore文件 在新建仓库时,有一个添加.gitignore 模板: .gitignore 是一个用于指定 Git 忽略特定文…

Mysql第四,五连弹

第四弹 一、&#x1f49b; 主键约束&#xff08;Primary key): 通过这个约束来指定某一个列作为主键&#xff08;1.非空&#xff0c;2.不能重复&#xff09; &#xff0c;主键&#xff1a;一条数据&#xff0c;身份标识&#xff08;类似于内存地址&#xff09; &#x1f604;&a…

Python爬虫Scrapy(二)_入门案例

入门案例 学习目标 创建一个Scrapy项目定义提取的结构化数据(Item)编写爬取网站的Spider并提取出结构化数据(Item)编写Item Pipelines来存储提取到的Item(即结构化数据) 一、新建项目(scrapy startproject) 在开始爬取之前&#xff0c;必须创建一个新的Scrapy项目。进入自定…

计算机毕设 深度学习人体跌倒检测 -yolo 机器视觉 opencv python

文章目录 0 前言1.前言2.实现效果3.相关技术原理3.1卷积神经网络3.1YOLOV5简介3.2 YOLOv5s 模型算法流程和原理4.数据集处理3.1 数据标注简介3.2 数据保存 5.模型训练 6 最后 0 前言 &#x1f525; 这两年开始毕业设计和毕业答辩的要求和难度不断提升&#xff0c;传统的毕设题…

[Round#14 Illuminate with your bril]

周末NSS的PWN专题&#xff0c;只作了3个&#xff0c;结束后跟NSS的师傅聊&#xff0c;对方确认了第4题的作法&#xff0c;重作成功。第5题看师傅的WP复现成功。 love 主函数给了个printf&#xff0c;这里可以得到所有地址&#xff0c;并且要求把v4,v5改相等 int __cdecl mai…

Linux 版本的 Abyss Locker 勒索软件针对 VMware ESXi 服务器

Abyss Locker 是最新开发的 Linux 加密器&#xff0c;旨在针对 VMware 的 ESXi 虚拟机平台对企业进行攻击。 随着企业从单个服务器转向虚拟机以实现更好的资源管理、性能和灾难恢复&#xff0c;勒索软件团伙创建了专注于针对该平台的加密器。 随着 VMware ESXi 成为最流行的虚…

UE5 摄像机与NPC重叠阻挡导致视角闪现的解决方法

文章目录 前言问题背景问题剖析摄像机碰撞分析解决方法总结前言 本文基于虚幻5.2.1版本,对摄像机与NPC重叠阻挡导致视角闪现提供一个解决方案,并深入讲解摄像机碰撞原理,提升大家的思维与解决问题的能力。 问题背景 当我们被NPC攻击或者NPC介于摄像机与玩家之间导致摄像机…

小研究 - JVM GC 对 IMS HSS 延迟分析(二)

用户归属服务器&#xff08;IMS HSS&#xff09;是下一代通信网&#xff08;NGN&#xff09;核心网络 IP 多媒体子系统&#xff08;IMS&#xff09;中的主要用户数据库。IMS HSS 中存储用户的配置文件&#xff0c;可执行用户的身份验证和授权&#xff0c;并提供对呼叫控制服务器…

微服务入门---Docker

微服务入门---Docker 1.初识Docker1.1.什么是Docker1.1.1.应用部署的环境问题1.1.2.Docker解决依赖兼容问题1.1.3.Docker解决操作系统环境差异1.1.4.小结 1.2.Docker和虚拟机的区别1.3.Docker架构1.3.1.镜像和容器1.3.2.DockerHub1.3.3.Docker架构1.3.4.小结 1.4.安装Docker 2.…

Flutter环境搭建踩坑集锦

Flutter 背景准备工作先检查一下自己的电脑&#xff0c;看一下是不是满足配置要求下载安装配置环境下载安装JDK下载安装Android studio下载Flutterflutter doctor故障Android license status unknownNetwork resources 故障 后记 背景 发现一个不错的框架Flutter&#xff0c;听…

web题型

0X01 命令执行 漏洞原理 没有对用户输入的内容进行一定过滤直接传给shell_exec、system一类函数执行 看一个具体例子 cmd1|cmd2:无论cmd1是否执行成功&#xff0c;cmd2将被执行 cmd1;cmd2:无论cmd1是否执行成功&#xff0c;cmd2将被执行 cmd1&cmd2:无论cmd1是否执行成…

【C++继承】

目录 一、继承的概念及定义1.1继承的概念1.2继承的定义1.2.1定义格式1.2.2继承方式与访问限定符的组合 二、基类和派生类对象赋值转换三、继承中的作用域四、派生类的默认成员函数五、继承与友元六、继承与静态成员七、复杂的菱形继承及菱形虚拟继承八、虚拟继承的原理 一、继承…

(AcWing)满足条件的01序列

给定 n 个 0 和 n 个 1&#xff0c;它们将按照某种顺序排成长度为 2n 的序列&#xff0c;求它们能排列成的所有序列中&#xff0c;能够满足任意前缀序列中 0 的个数都不少于 1 的个数的序列有多少个。 输出的答案对 10^97 取模。 输入格式 共一行&#xff0c;包含整数 n。 …

Kotlin基础(十):函数进阶

前言 本文主要讲解kotlin函数&#xff0c;之前系列文章中提到过函数&#xff0c;本文是kotlin函数的进阶内容。 Kotlin文章列表 Kotlin文章列表: 点击此处跳转查看 目录 1.1 函数基本用法 Kotlin 是一种现代的静态类型编程语言&#xff0c;它在函数的定义和使用上有一些特点…

软考A计划-系统集成项目管理工程师-项目干系人管理-上

点击跳转专栏>Unity3D特效百例点击跳转专栏>案例项目实战源码点击跳转专栏>游戏脚本-辅助自动化点击跳转专栏>Android控件全解手册点击跳转专栏>Scratch编程案例点击跳转>软考全系列点击跳转>蓝桥系列 &#x1f449;关于作者 专注于Android/Unity和各种游…