基础功能
- 根据单个链接下载文件到本地
- 根据多个链接同时下载文件到本地
- 下载中的状态
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
网友评论