浅析hooks,复杂前端业务解题之道

news2024/11/17 13:56:10

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/814383.html

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

相关文章

VS2017配置Qt开发环境

VS2017配置Qt开发环境 安装Qt5.12.11安装Qt插件在VS2017中进行设置参考教程 安装Qt5.12.11 安装Qt插件 在VS2017中进行设置 参考教程 # Qt下载地址 https://download.qt.io/ # Qt安装 https://blog.csdn.net/jjxcsdn/article/details/125432165?spm1001.2014.3001.5506 # VS2…

【LeetCode】解码方法(动态规划)

解码方法 题目描述算法流程编程代码代码优化 链接: 解码方法 题目描述 算法流程 编程代码 class Solution { public:int numDecodings(string s) {int n s.size();vector<int> dp(n);dp[0] s[0] ! 0;if(n 1) return dp[0];if(s[1] < 9 && s[1] > 1) d…

Packet Tracer – 使用 TFTP 服务器升级思科 IOS 映像。

Packet Tracer – 使用 TFTP 服务器升级思科 IOS 映像。 地址分配表 设备 接口 IP 地址 子网掩码 默认网关 R1 F0/0 192.168.2.1 255.255.255.0 不适用 R2 G0/0 192.168.2.2 255.255.255.0 不适用 S1 VLAN 1 192.168.2.3 255.255.255.0 192.168.2.1 TFTP …

Neo4j文档阅读笔记-Installation and Launch Guide

安装&#xff08;Windows&#xff09; ①找到下载好的Neo4j Desktop文件&#xff0c;然后双击进行安装&#xff1b; ②安装Neo4j Desktop根据下一步进行安装。 启动 ①激活 打开Neo4j Desktop应用程序后&#xff0c;将激活码输入到“Activation Key”窗口中。 ②创建数据库…

牛客网Verilog刷题——VL44

牛客网Verilog刷题——VL44 题目题目解析答案 题目 如图所示为两种状态机中的一种&#xff0c;请根据状态转移图写出代码&#xff0c;状态转移线上的0/0等表示的意思是过程中data/flag的值。 要求&#xff1a; 1、 必须使用对应类型的状态机 2、 使用二段式描述方法 注意rs…

远程医疗技术的变革

目录 1.远程医疗的概念 2.远程医疗的发展历史 3.远程医疗的靠谱性 4.远程医疗的潜在危害 1.远程医疗的概念 远程医疗是一种通过通信技术&#xff0c;使医生和患者能够在不同地点进行医疗咨询和治疗的形式。它利用视频通话、电话、在线聊天和其他远程通信工具来实现远程诊断…

自定义一个仿拼多多地址选择器

前言 做了一个仿拼多多的地址选择器&#xff0c;但是与拼多多实现方法有些出入&#xff0c;大体效果是差不多的。废话不多说&#xff0c;先上一张效果动图&#xff1a; 开始 先说说本文的一些概念。地区级别&#xff1a;就是比如省级&#xff0c;市级&#xff0c;县级&#x…

理解复杂系统的关键:耐心

理解复杂系统的关键&#xff1a;耐心 复杂系统本质上是多面的、复杂的。它们通常并非被设计成一瞬间就能理解的。这对于自然发生的系统&#xff0c;如生态系统&#xff0c;和人类设计的系统&#xff0c;如高级软件或机械&#xff0c;都是适用的。这些系统是由多个组件混合而成…

【腾讯云Cloud Studio实战训练营】使用Cloud Studio迅捷开发一个3D家具个性化定制应用

目录 前言&#xff1a; 一、腾讯云 Cloud Studio介绍&#xff1a; 1、接近本地 IDE 的开发体验 2、多环境可选&#xff0c;或连接到云主机 3、随时分享预览效果 4、兼容 VSCode 插件 5、 AI代码助手 二、腾讯云Cloud Studio项目实践&#xff08;3D家具个性化定制应用&…

牛客网Verilog刷题——VL42

牛客网Verilog刷题——VL42 题目答案 题目 请设计一个可以实现任意小数分频的时钟分频器&#xff0c;比如说8.7分频的时钟信号&#xff0c;注意rst为低电平复位。提示&#xff1a;其实本质上是一个简单的数学问题&#xff0c;即如何使用最小公倍数得到时钟周期的分别频比。设小…

一夜卷走220万美元

* * * 原创&#xff1a;刘教链 * * * 号外&#xff1a;今天在「刘教链内参」发表了《内参&#xff1a;对传国内某DAO组织被刑事立案一事的分析》&#xff0c;欢迎关注公众号「刘教链内参」并阅读。 --- 隔夜比特币继续在29k上方盘旋。 表面的百无聊赖之下&#xff0c;各种土狗…

隐私保护之隐私信息检索

【引子】用户的隐私保护涉及多个方面&#xff0c;用户行为的隐私保护更是一个难点。周末读了一篇论文&#xff0c;https://cacm.acm.org/magazines/2010/4/81501-private-information-retrieval/fulltext&#xff0c;涉及了很多数学上的方法和概念&#xff0c;很是费劲&#xf…

Python--matplotlib基础绘图

前言 本章来说一下绘图&#xff0c;毕竟在软硬件行业&#xff0c;设备端的日志有了&#xff0c;前面也讲了抽取数据&#xff0c;怎么能不绘图呢。 在工作中&#xff0c;我也是经常会遇到研发有这样的需求&#xff0c;把数据整理出来&#xff0c;做成图&#xff0c;便于分析BUG。…

类变量和类方法

类变量和类方法 引入 思考&#xff1a;有一群小孩在玩堆雪人&#xff0c;不时有新的小孩加入&#xff0c;请问如何知道现在有多少小孩在玩&#xff1f; 静态变量内存分析 1、静态变量被对象共享 2、静态变量可能在堆中&#xff0c;也可能在方法区的静态域中&#xff0c;这…

Python中的类和实例是什么意思

目录 python中的类是什么 python中的实例是什么 python中的类和实例有什么区别 总结 python中的类是什么 在Python中&#xff0c;类是一种用于创建对象的蓝图或模板。类定义了对象的属性和方法。对象是类的实例&#xff0c;它拥有类定义的属性和方法。 通过定义类&#xff…

【Ajax】笔记-JQuery发送jsonp请求

前端 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>jQuery-jsonp</title><style>#re…

Linux安装操作(Mac版本)

Parallels Desktop的简介 Parallels Desktop是Mac平台上的虚拟机软件&#xff0c;也是Mac平台最好的虚拟机软件之一。它允许用户在Mac OS X系统上同时运行其他操作系统&#xff0c;例如Windows、Linux等。Parallels Desktop为Mac用户提供了使用其他操作系统和软件的便利性&…

如何在Delphi中用CnPack的魔法,快速搭建你的项目结构(cnwizard)

1、打开工具&#xff0c;如下图。 2、使用现有模板创建文件夹结构。 按照树状结构创建文件夹结构&#xff1a; 1&#xff09;打开窗体。点击第一个图标。 2&#xff09;选择要创建文件夹结构的文件夹。 3&#xff09;结果如下&#xff1a; 3、模仿指定的一个文件夹结构创建。…

春秋云镜 CVE-2021-34257

春秋云镜 CVE-2021-34257 WPanel4-CMS Authenticated RCE漏洞 靶标介绍 WPanel是一个用于构建博客、网站和网络应用程序的CMS。 WPanel 4 4.3.1 及更低版本存在安全漏洞&#xff0c;该漏洞源于通过恶意 PHP 文件上传到 (1) 仪表板的头像图像、(2) 帖子文件夹图像、(3) 页面文…

简单理解 ChatGPT 和模型训练

介绍 这些令人着迷的对话机器人使用自然语言理解来理解输入。NLU 是自然语言处理的一个子集&#xff0c;使机器能够理解自然语言&#xff08;文本/音频&#xff09;。NLU 是大多数 NLP 应用程序&#xff08;例如机器翻译、语音识别、构建聊天机器人等&#xff09;中的关键组件。…