当前位置: 首页 > article >正文

vue3 Hooks函数使用及常用utils封装

hooks 是什么

vue3使用了composition API,我们可自定义封装hooks,达到复用,在Vue2中采取的mixins,对mixins而言, hooks更清楚复用功能代码的来源, 更清晰易懂。

简单来说:hooks 就是函数的一种写法,就是将文件的一些单独功能的 js 代码进行抽离出来进行封装使用 

 自定义 hook 需要满足的规范

具备可复用功能,才需要抽离为 hooks 独立文件

函数名前缀加上use开头,形如: useXX

合理利用Vue提供的响应式函数及生命周期

暴露出 变量 或 方法 提供外部需要时使用

 Hooks 常用 工具

src/hooks/index.ts

倒计时hooks 

import { ref, Ref, onBeforeMount } from 'vue';

/**
 *  倒计时hooks
 *  @param {Number} second 倒计时秒数
 *  @return {Number} count 倒计时秒数
 *  @return {Function} countDown 倒计时函数
 *  @example
 *  const { count, countDown } = useCountDown()
 *  countDown(60)
 *  <div>{{ count }}</div>
 */

export function useCountDown() {
  // 定义函数参数和返回值类型
  const count: Ref<number> = ref(0);
  const timer: Ref<NodeJS.Timeout | null> = ref(null);

  const countDown = (second: number, callback?: () => void) => {
    if (count.value === 0 && timer.value === null) {
      // 如果提供了回调函数,则调用它
      if (callback) callback();
      count.value = Number(second);
      timer.value = setInterval(() => {
        count.value--;
        if (count.value === 0) {
          clearInterval(timer.value!);
          timer.value = null;
        }
      }, 1000);
    }
  };

  onBeforeMount(() => {
    // 确保 timer 有值再清除
    timer.value && clearInterval(timer.value);
  });

  return {
    count,
    countDown,
  };
}
<template>
  <button :disabled="count !== 0" @click="countDown(3, logCountdown)">倒计时剩余 {{ `${count}秒` }} </button>
</template>

<script lang="ts" setup name="HomePage">
  import { useCountDown } from '@/hooks';
  // 倒计时
  const { count, countDown } = useCountDown();

  const logCountdown = () => {
    console.log('触发倒计时回调函数');
  };
</script>

防抖hooks

import { ref, Ref, onBeforeMount } from 'vue';

/**
 * 防抖hooks
 * @params {Function} fn  需要防抖的函数 delay 防抖时间
 * @returns {Function} debounce 防抖函数
 * @example
 * const { debounce } = useDebounce()
 * const fn = () => { console.log('防抖') }
 * const debounceFn = debounce(fn, 1000)
 * debounceFn()
 */

// 防抖函数的类型
interface DebounceFunction {
  (fn: (...args: any[]) => void, delay: number): (...args: any[]) => void;
}

export function useDebounce(): { debounce: DebounceFunction } {
  const debounce: DebounceFunction = (fn, delay) => {
    let timer: ReturnType<typeof setTimeout> | null = null;
    return function (this: any, ...args: any[]) {
      if (timer) clearTimeout(timer);
      timer = setTimeout(() => {
        fn.apply(this, args);
      }, delay);
    };
  };

  return { debounce };
}
<template>
  <button @click="debounceClick">防抖点击</button>
</template>

<script lang="ts" setup name="HomePage">
  import { useDebounce } from '@/hooks';
  // 防抖
  const { debounce } = useDebounce();

  const fn = () => {
    console.log('取消点击一秒后打印');
  };
  const debounceClick = debounce(fn, 1000);
</script>

节流hooks

import { ref, Ref, onBeforeMount } from 'vue';

/**
 * 节流hooks
 * @params {Function} fn  需要节流的函数 delay 节流时间
 * @returns {Function} throttle 节流函数
 * @example
 * const { throttle } = useThrottle()
 * const fn = () => { console.log('节流') }
 * const throttleFn = throttle(fn, 1000)
 * throttleFn()
 */

// 节流函数的类型
interface ThrottleFunction {
  (fn: (...args: any[]) => void, delay: number): (...args: any[]) => void;
}

export function useThrottle(): { throttle: ThrottleFunction } {
  const throttle: ThrottleFunction = (fn, delay) => {
    let timer: ReturnType<typeof setTimeout> | null = null;
    return function (this: any, ...args: any[]) {
      if (!timer) {
        timer = setTimeout(() => {
          fn.apply(this, args);
          timer = null;
        }, delay);
      }
    };
  };

  return { throttle };
}
<template>
  <button @click="throttleClick">节流点击</button>
</template>

<script lang="ts" setup name="HomePage">
  import { useThrottle } from '@/hooks';
  const fn = () => {
    console.log('一秒内只打印一次');
  };
  const { throttle } = useThrottle();
  const throttleClick = throttle(fn, 1000);
</script>

http://www.kler.cn/a/160501.html

相关文章:

  • 开源项目推荐——OpenDroneMap无人机影像数据处理
  • 【AI日记】24.11.14 复习和准备 RAG 项目 | JavaScript RAG Web Apps with LlamaIndex
  • 淘宝代购系统;海外代购系统;代购程序,代购系统源码PHP前端源码
  • Elasticsearch 8.16:适用于生产的混合对话搜索和创新的向量数据量化,其性能优于乘积量化 (PQ)
  • MFC工控项目实例二十九主对话框调用子对话框设定参数值
  • Linux 系统管理和监控命令---- auditctl命令
  • LeetCode双指针:第一个错误的版本
  • Redis Reactor事件驱动模型源码
  • Linux-centos上如何配置管理NFS服务器?
  • 数据分析中的绝地反击:如何解救一个陷入困境的数据模型
  • IDEA切换Python虚拟环境
  • Vue3计算属性与监听属性和生命周期
  • Linux网卡命名规则
  • Spring Boot学习(三十三):集成kafka
  • 让关节远离疼痛,重拾健康活力
  • Java架构师系统架构设计原则应用
  • 13款趣味性不错(炫酷)的前端动画特效及源码(预览获取)分享(附源码)
  • 解决Error:You‘re using an RSA key with SHA-1, which is no longer allowed
  • 多关键字排序(java实训)
  • HarmonyOS4.0从零开始的开发教程04 初识ArkTS开发语言(下)
  • 机器学习---pySpark案例
  • 深入理解Vue.js中的this:解析this关键字及其使用场景
  • uniapp实战 —— 分类导航【详解】
  • 设置webstorm和idea符合Alibaba规范
  • 【Docker】从零开始:17.Dockerfile基本概念
  • 指定分隔符对字符串进行分割 numpy.char.split()