Vue.js 学习总结(11)—— Vue3 Hook 函数实战总结

前言

在 Vue 3 中,Hook 函数是一种特殊的函数,用于封装可重用的逻辑和状态管理。Hook 函数允许你在 Vue 组件中提取和复用逻辑,而不是将所有逻辑都放在组件的选项对象中。它们可以帮助你更好地组织代码,提高代码的可维护性和可测试性。Hook 函数的特点:

  1. 可重用性:Hook 函数可以在多个组件中重复使用,避免了重复编写相同的逻辑。

  2. 逻辑封装:将特定的逻辑封装在 Hook 函数中,使组件的代码更加清晰和易于理解。

  3. 状态管理:Hook 函数可以用于管理组件的状态,包括响应式数据和副作用。

  4. 测试友好:由于 Hook 函数是独立的函数,可以更容易地进行单元测试。

一、Hook 函数的使用方法

创建 Hook 函数,Hook 函数通常是一个普通的 JavaScript 函数,可以接受参数并返回一个对象或函数。例如,以下是一个简单的 Hook 函数,用于管理一个计数器:

import { reactive, toRefs } from 'vue';
   export function useCounter(initialValue = 0) {
     const state = reactive({
       count: initialValue,
     });
     const increment = () => {
       state.count++;
     };
     const decrement = () => {
       state.count--;
     };
     return {
      ...toRefs(state),
       increment,
       decrement,
     };
   }

二、在组件中使用 Hook 函数

在 Vue 组件中,可以通过导入 Hook 函数并调用它来使用其中的逻辑和状态。例如,以下是一个使用 useCounter Hook 函数的组件:

<template>
     <div>
       <p>Count: {{ count }}</p>
       <button @click="increment">Increment</button>
       <button @click="decrement">Decrement</button>
     </div>
   </template>

   <script>
   import { useCounter } from './hooks/useCounter';

   export default {
     setup() {
       const { count, increment, decrement } = useCounter();
       return {
         count,
         increment,
         decrement,
       };
     },
   };
</script>

三、Hook 函数的应用场景

  1. 状态管理:Hook 函数可以用于管理组件的状态,例如计数器、表单数据、加载状态等。

  2. 副作用管理:可以使用 Hook 函数来管理副作用,如订阅事件、定时器、异步请求等。

  3. 逻辑复用:将通用的逻辑封装在 Hook 函数中,以便在多个组件中重复使用,例如数据验证、权限检查等。

四、常见的 HOOK 函数案例

一、数据获取 Hook。假设你经常需要在不同组件中进行数据获取操作,可以创建一个数据获取 Hook。

import { ref, onMounted } from 'vue';

export function useDataFetch(apiUrl) {
  const data = ref(null);
  const loading = ref(true);
  const error = ref(null);

  onMounted(async () => {
    try {
      const response = await fetch(apiUrl);
      if (!response.ok) {
        throw new Error('Network response was not ok');
      }
      data.value = await response.json();
    } catch (err) {
      error.value = err;
    } finally {
      loading.value = false;
    }
  });

  return { data, loading, error };
}

 使用示例:

<template>
  <div v-if="loading">Loading...</div>
  <div v-else-if="error">{{ error.message }}</div>
  <div v-else>
    <!-- 展示获取到的数据 -->
    <p>{{ data.someProperty }}</p>
  </div>
</template>

<script>
import { useDataFetch } from './yourHooks';

export default {
  setup() {
    const { data, loading, error } = useDataFetch('https://your-api-url.com/data');
    return { data, loading, error };
  },
};
</script>

 二、表单验证 Hook。用于处理表单验证逻辑。

import { ref } from 'vue';

export function useFormValidation() {
  const formData = ref({});
  const errors = ref({});

  const validate = () => {
    // 假设这里进行一些简单的验证,比如检查某个字段是否为空
    if (!formData.value.username) {
      errors.value.username = 'Username is required';
    } else {
      delete errors.value.username;
    }
    // 可以根据实际需求扩展更多验证逻辑
    return Object.keys(errors.value).length === 0;
  };

  return { formData, errors, validate };
}

使用示例:

<template>
  <form @submit.prevent="submitForm">
    <input v-model="formData.username" />
    <p v-if="errors.username">{{ errors.username }}</p>
    <button>Submit</button>
  </form>
</template>

<script>
import { useFormValidation } from './yourHooks';

export default {
  setup() {
    const { formData, errors, validate } = useFormValidation();
    const submitForm = () => {
      if (validate()) {
        // 处理表单提交逻辑
      }
    };
    return { formData, errors, submitForm };
  },
};
</script>

三、鼠标位置跟踪 Hook。跟踪鼠标在页面上的位置

 使用示例:

<template>
  <div>Mouse position: {{ x }}, {{ y }}</div>
</template>

<script>
import { useMousePosition } from './yourHooks';

export default {
  setup() {
    const { x, y } = useMousePosition();
    return { x, y };
  },
};
</script>

五、Vue3 自定义 Hooks 为什么这么好用?

1、组合式 API 和选项 API

Vue2 提供的编程方式是 Options API,即选项式 API。我们需要在 data 里面定义变量,在 methods 里面定义方法,在 computed 定义计算后的逻辑。

图片

在开发功能的时候,我们需要在 data 、methods、computed 之间来回找代码。如果功能非常复杂, data 、methods、computed 等里面的代码就会非常长,不好维护。

图片

后来 Vue3 出现了,它提供的编程方式是 Composition API,即组合式 API。在开发功能的时候,我们根据逻辑功能去组织代码,一个功能所定义的所有 API 会放在一起。

图片

但是如果业务功能太复杂,script 标签里面的代码也会又臭又长,而且并不是很多人都有加注释的习惯,所以时间长了也不好维护。

图片

那能不能把相同逻辑功能的代码分别放到到不同的文件里,其他地方想用的时候直接导入就可以复用了呢?有的,自定义 Hooks 出现了。

2、自定义 Hooks 介绍

Vue 的自定义 Hooks 是一种封装可重用逻辑的方式。它允许你将复杂的逻辑提取出来,形成独立的函数,然后在不同的组件中复用。这样可以避免在多个组件中重复编写相同的逻辑,提高代码的可读性和可维护性。通俗易懂来说就是:

1.将可复用的功能逻辑放到一个 js 文件里面,并通过 export  导出。

2.定义 Hooks 的时候,js 的文件名和方法名通常以 use 开头,例如 useAddOrder、useChangeData。

3.通过 import  导入相关的 js 文件,引用时通过解构显示相关的变量和方法。

3、自定义 Hooks 案例

3.1 案例1

创建一个简单的计数器 Hooks

图片

使用 Hooks

<template>
  <div>
    <p>count: {{ count }}</p>
    <el-divider></el-divider>
    <el-button type="primary" @click="increment">新增</el-button>
    <el-button type="success" @click="decrement">减少</el-button>
  </div>
</template>
<script setup>
// 导入 hooks
import { useCounter } from "../hooks/useCounter";
// 解构引入
const { count, increment, decrement } = useCounter();
</script>

图片

3.2 案例2

创建一个监听浏览器窗口大小变化的 Hooks

图片

使用 Hooks

<template>
  <div>
     <p>浏览器窗口宽度: {{ width }}</p>
    <p>浏览器窗口高度: {{ height }}</p>
  </div>
</template>
<script setup>
// 导入 hooks
import { useWindowResize } from "../hooks/useWindowResize";
// 解构引入
const { width, height } = useWindowResize();
</script>

图片

4、自定义 Hooks 优势

所谓的自定义 Hooks 就是在开发 Vue3 项目时,我们将 script 里面相同逻辑功能的变量和方法等封装到一个 js 文件里面,然后通过 export导出。然后在任何页面都可以通过导入、解构的方式使用,大大提高代码的复用性。自定义 Hooks 将相同的功能代码从一堆代码中解耦出来,让组件结构更清晰,便于维护。

图片

Hooks 直译是“钩子”,所以又把这些定义的 js 叫做钩子函数。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

算法题总结(十九)——图论

图论 DFS框架 void dfs(参数) { if (终止条件) {存放结果;return; }for (选择&#xff1a;本节点所连接的其他节点) {处理节点;dfs(图&#xff0c;选择的节点); // 递归回溯&#xff0c;撤销处理结果 } }深搜三部曲 确认递归函数&#xff0c;参数确认终止条件处理目前搜索节…

JAVA基础:IO流 (学习笔记)

IO流 一&#xff0c;IO流的理解 i &#xff1a; input 输入 o&#xff1a;output 输入 流&#xff1a;方式&#xff0c;传递数据的方式---------相当于生活中的“管道”&#xff0c;“车”&#xff0c;将资源从一个位置&#xff0c;传递到另一个位置 二&#xff0c;IO流的分…

从0开始深度学习(16)——暂退法(Dropout)

上一章的过拟合是由于数据不足导致的&#xff0c;但如果我们有比特征多得多的样本&#xff0c;深度神经网络也有可能过拟合 1 扰动的稳健性 经典泛化理论认为&#xff0c;为了缩小训练和测试性能之间的差距&#xff0c;应该以简单的模型为目标&#xff0c;即模型以较小的维度的…

Qt中使用线程之QConcurrent

QConcurrent可以实现并发&#xff0c;好处是我们可以不用单独写一个类了&#xff0c;直接在类里面定义任务函数&#xff0c;然后使用QtConcurrent::run在单独的线程里执行一个任务 1、定义一个任务函数 2、定义1个QFutureWatcher的对象&#xff0c;使用QFutureWatcher来监测任…

新手直播方案

简介 新手直播方案 &#xff0c;低成本方案 手机/电脑 直接直播手机软件电脑直播手机采集卡麦电脑直播多摄像机 机位多路采集卡 多路麦加电脑&#xff08;高成本方案&#xff09; 直播推流方案 需要摄像头 方案一 &#xff1a;手机 电脑同步下载 网络摄像头 软件&#xff08…

【学术论文投稿】Windows11开发指南:打造卓越应用的必备攻略

【IEEE出版南方科技大学】第十一届电气工程与自动化国际会议&#xff08;IFEEA 2024)_艾思科蓝_学术一站式服务平台 更多学术会议论文投稿请看&#xff1a;https://ais.cn/u/nuyAF3 目录 引言 一、Windows11开发环境搭建 二、Windows11关键新特性 三、Windows11设计指南 …

小程序开发实战:PDF转换为图片工具开发

目录 一、开发思路 1.1 申请微信小程序 1.2 编写后端接口 1.3 后端接口部署 1.4 微信小程序前端页面开发 1.5 运行效果 1.6 小程序部署上线 今天给大家分享小程序开发系列&#xff0c;PDF转换为图片工具的开发实战&#xff0c;感兴趣的朋友可以一起来学习一下&#xff01…

linux中级(NFS服务器)

NFS&#xff1a;用于在NNIX/Linux主机之间进行文件共享的协议 流程&#xff1a;首先服务端开启RPC服务&#xff0c;并开启111端口&#xff0c;服务器端启动NFS服务&#xff0c;并向RPC注册端口信息&#xff0c;客户端启动RPC&#xff0c;向服务器RPC服务请求NFS端口&#xff0…

anaconda 创建环境失败 解决指南

anaconda 创建环境失败 解决指南 一、问题描述 我在宿舍有一台电脑。由于我经常泡在实验室&#xff0c;所以那台电脑不是经常用&#xff0c;基本吃灰。昨天晚上突然有在那台电脑上使用Camel-AI部署多智能体协同需求&#xff0c;便戳开了电脑&#xff0c;问题也随之而来。 当…

汽车级DC-DC转换器英飞凌TLF35584

上汽荣威都在用的汽车级DC-DC转换器英飞凌TLF35584 今天平台君从IPBrain数据库中给大家带来的一款由Infineon(英飞凌)推出的一款多路输出安全电源芯片,具备高可靠性和安全性。适用于汽车电子系统中的多种应用场景,如车身控制、安全气囊、防抱死制动系统,电子稳定控制系统等。…

设计模式基础知识以及典型设计模式总结(上)

1. 基础 1. 什么是设计模式&#xff1f; 设计模式是指在软件开发中&#xff0c;经过验证的&#xff0c;用于解决在特定环境下重复出现的特定问题的解决方案。 简单的说&#xff0c;设计模式是解决问题的固定套路。 慎用设计模式。 2. 设计模式是怎么来的&#xff1f; 满足…

Unity3D学习FPS游戏(4)重力模拟和角色跳跃

前言&#xff1a;前面两篇文章&#xff0c;已经实现了角色的移动和视角转动&#xff0c;但是角色并没有办法跳跃&#xff0c;有时候还会随着视角移动跑到天上。这是因为缺少重力系统&#xff0c;本篇将实现重力和角色跳跃功能。觉得有帮助的话可以点赞收藏支持一下&#xff01;…

fmql之Linux RTC

模拟i2c&#xff0c;连接rtc芯片。 dts&#xff1a; /{ // 根节点i2c_gpio: i2c-gpio {#address-cells <1>;#size-cells <0>;compatible "i2c-gpio";// MIO56-SDA, MIO55-SCL // 引脚编号gpios <&portc 2 0&portc 1 0 >;i2c-gp…

Unity3D学习FPS游戏(2)简单场景、玩家移动控制

前言&#xff1a;上一篇的时候&#xff0c;我们已经导入了官方fps的素材&#xff0c;并且对三维模型有了一定了解。接下来我们要构建一个简单的场景让玩家能够有地方移动&#xff0c;然后写一个简单的玩家移动控制。 简单场景和玩家移动 简单场景玩家移动控制玩家模型视野-摄像…

单细胞配色效果模拟器 | 简陋版(已有颜色数组)

目的&#xff1a;假设你有一组颜色了&#xff0c;怎么模拟查看它们在单细胞DimPlot中的美学效果呢&#xff1f;要足够快&#xff0c;还要尽可能有模拟效果。 1. 尝试1: 随机矩阵&#xff0c;真的UMAP降维后绘图&#xff08;失败&#xff09; 造一个随机矩阵&#xff0c;使用S…

华为鸿蒙HarmonyOS应用开发者高级认证视频及题库答案

华为鸿蒙开发者高级认证的学习资料 1、课程内容涵盖HarmonyOS系统介绍、DevEco Studio工具使用、UI设计与开发、Ability设计与开发、分布式特性、原子化服务卡片以及应用发布等。每个实验都与课程相匹配&#xff0c;帮助加深理解并掌握技能 2、学习视频资料 华为HarmonyOS开发…

全能大模型GPT-4o体验和接入教程

GPT-4o体验和接入教程 前言一、原生API二、Python LangchainSpring AI总结 前言 Open AI发布了产品GPT-4o&#xff0c;o表示"omni"&#xff0c;全能的意思。 GPT-4o可以实时对音频、视觉和文本进行推理&#xff0c;响应时间平均为 320 毫秒&#xff0c;和人类之间对…

动态规划 —— 斐波那契数列模型-解码方法

1. 解码方法 题目链接&#xff1a; 91. 解码方法 - 力扣&#xff08;LeetCode&#xff09;https://leetcode.cn/problems/decode-ways/description/ 2. 题目解析 1. 对字母A - Z进行编码1-26 2. 11106可以解码为1-1-10-6或者11-10-6, 但是11-1-06不能解码 3. 0n不能解码 4. …

微知-Lecroy力科的PCIe协议分析仪型号命名规则(PCIe代,金手指lanes数量)

文章目录 要点主要型号命名规则各代主要产品图片Summit M616 协议分析仪/训练器Summit T516 分析仪Summit T416 分析仪Summit T3-16分析仪Summit T28 分析仪 综述 要点 LeCroy(力科)成立于1964年&#xff0c;是一家专业生产示波器厂家。在美国纽约。一直把重点放在研制改善生产…

【Linux】线程池详解及其基本架构与单例模式实现

目录 1.关于线程池的基本理论 1.1.线程池是什么&#xff1f; 1.2.线程池的应用场景&#xff1a; 2.线程池的基本架构 2.1.线程容器 2.2.任务队列 2.3.线程函数&#xff08;HandlerTask&#xff09; 2.4.线程唤醒机制 3.添加单例模式 3.1.单例模式是什么&…