美文网首页React
自定义 hook —— useDownload

自定义 hook —— useDownload

作者: Lia代码猪崽 | 来源:发表于2021-11-02 15:36 被阅读0次

基础功能

  1. 根据单个链接下载文件到本地
  2. 根据多个链接同时下载文件到本地
  3. 下载中的状态 state

具体实现代码

import { useState } from 'react'
import { message, Modal } from 'antd'

// urlPrefix 下载链接的前缀,如 window.location.host 等
const useDownLoad = (urlPrefix = '') => {
  // 批量下载按钮用到的 loading 状态
  const [downloadLoading, setDownloadLoading] = useState(false)

  // 使用 iframe 的方法下载,window.open 或 a 标签 download 属性会拦截多次下载
  const createIFrame = (
    url,
    triggerDelay,  
    removeDelay,
    isEnd,
    isBatchDownload
  ) => {
    // 动态添加 iframe ,设置 src ,然后删除
    setTimeout(() => {
      var frame = document.createElement('iframe')
      frame.src = url  // 去加载,才会下载
      frame.style.display = 'none'  // 用户无感的关键,不展示
      document.body.appendChild(frame)  // 直接加到 body 底部
      // 关闭 loading 状态和 iframe 的延迟回调
      setTimeout(function() {
        if (isEnd && isBatchDownload) {  // 结束后关闭批量的 loading 状态
          setDownloadLoading(false)
        }
        frame.remove()
      }, removeDelay)
    }, triggerDelay)
  }
}

  // 统一封装的下载函数,voiceUrlArray 为下载的 url 数组,isBatchDownload 为是否批量下载
  const download = (voiceUrlArray, isBatchDownload) => {
    if (voiceUrlArray?.length === 0) {
      message.error('下载失败')
      return
    }
    if (isBatchDownload) {
      setDownloadLoading(true)
    }
    let triggerDelay = 100  // 切换下载下一个文件的间隔时间
    let removeDelay = 2000  // 打开 iframe 到关闭 iframe 的间隔时间
    // 遍历 url 数组,开始下载
    voiceUrlArray.forEach((item, index) => {
      createIFrame(
        urlPrefix + item,  // 下载 url
        index * triggerDelay,  // 按顺序排队队打开,所以要用到 index
        removeDelay,  // 打开 iframe 到关闭 iframe 的间隔时间
        index === voiceUrlArray.length - 1,  // 是否是最后一个
        isBatchDownload  // 是否批量下载,如果还已经是最后一个要关闭 loading 状态的
      )
    })
  }

  // 会 return 出去的下载单个文件的方法
  const handleDownload = voiceUrl => {
    if (!voiceUrl) {
      message.error('下载失败')
      return
    }
    // 包装成数组,复用 download 方法
    download([voiceUrl], false)
  }

  // 会 return 出去的批量下载多个文件的方法
  const handleBatchDownload = (selectedRows, voiceUrlKey = '') => {
    if (selectedRows.length <= 0) {
      Modal.info({
        title: '提示',
        content: '请先选择文件',
        onOk() {}
      })
      return
    }
    let arr = []
    selectedRows.forEach(item => {
      // selectedRows 可能为对象数组,也可能为字符串数组
      arr = [...arr, ...([voiceUrlKey ? item[voiceUrlKey] : item] || [])]
    })
    download(arr)
  }

 return {
    downloadLoading,
    handleDownload,
    handleBatchDownload
  }
}

export default useDownLoad

相关文章

  • 自定义 hook —— useDownload

    基础功能 根据单个链接下载文件到本地 根据多个链接同时下载文件到本地 下载中的状态 state 具体实现代码

  • 在React中创建自定义hook

    什么是自定义hook? 使用自定义hook可以将某些组件逻辑提取到可重用的函数中。 自定义hook是一个从use开...

  • react的一些总结

    什么时候自定义Hook? 当多个组件之间有一些公共的逻辑,可以将他们抽取成自定义的Hook,Hook本质是自定义的...

  • 自定义Hook & 高阶组件

    自定义Hook 自定义Hook: 将一些常用的、跨越多个组件的Hook功能,抽离出去形成一个函数,该函数就是自定义...

  • 自定义hook

    自定义hook 需求描述:自定义一个hook函数,实现获取滚动距离Y const [y] = useWindowS...

  • fishHook-代码实例

    可以HOOK系统的C函数,但无法HOOK自定义的函数 fishHook 无法交换自定义函数!!!,这个函数肯定是C...

  • DebugValue Hook

    DebugValue Hook useDebugValue:用于将自定义Hook的关联数据显示到调试栏 如果创建的...

  • [react]24、自定义hooks

    1、自定义Hook的基本使用 自定义Hook本质上只是一种函数代码逻辑的抽取,严格意义上来说,它本身并不算Reac...

  • Hook

    Hook 概念和特点 useState useRef EffectHook 自定义钩子 useCallback u...

  • 记一次git hook踩坑(python编写hook脚本)

    背景:项目内有个zip包需要发版时去网上更新,自定义一个pre-commit hook来解决。 hook逻辑编写(...

网友评论

    本文标题:自定义 hook —— useDownload

    本文链接:https://www.haomeiwen.com/subject/gzoxzltx.html