feat: 下载组件
This commit is contained in:
96
packages/download-link/index.vue
Normal file
96
packages/download-link/index.vue
Normal file
@ -0,0 +1,96 @@
|
||||
<!--
|
||||
* @Author: zhaojinfeng 121016171@qq.com
|
||||
* @Date: 2023-07-21 01:21:34
|
||||
* @LastEditors: zhaojinfeng 121016171@qq.com
|
||||
* @LastEditTime: 2023-07-21 01:51:17
|
||||
* @FilePath: \vue3\packages\download-link\index.vue
|
||||
* @Description: 现在组件
|
||||
*
|
||||
-->
|
||||
<template>
|
||||
<el-link v-loading="loading" :href="url" :type="type" :download="url && fileName" @click="download">
|
||||
<slot>
|
||||
{{ fileName }}
|
||||
</slot>
|
||||
</el-link>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup name="ThDownloadLink">
|
||||
import { saveAs } from 'file-saver'
|
||||
|
||||
const props = withDefaults(defineProps<{
|
||||
/**
|
||||
* 自定义下载文件名
|
||||
*
|
||||
*/
|
||||
fileName?: string
|
||||
/**
|
||||
* 下载文件的请求源
|
||||
*
|
||||
* 可以是文件名或URL。
|
||||
*
|
||||
*/
|
||||
src?: number | string | FileVO
|
||||
/** 下载文件的请求参数的健名 */
|
||||
requestKey?: string
|
||||
/** 下载文件的请求函数 */
|
||||
request?: (...args: any) => Promise<Blob>
|
||||
}>(), {
|
||||
fileName: '文件',
|
||||
requestKey: 'fileName',
|
||||
request: () => {
|
||||
throw new Error('请定义下载接口的请求函数')
|
||||
},
|
||||
})
|
||||
|
||||
let url = $ref('')
|
||||
let loading = $ref(false)
|
||||
|
||||
let type = $ref<'success' | 'primary' | 'danger'>('primary')
|
||||
|
||||
async function downloadByRequest(fileName: string | number) {
|
||||
if (url || loading)
|
||||
return
|
||||
loading = true
|
||||
try {
|
||||
const res = await props.request({ [props.requestKey]: fileName })
|
||||
url = URL.createObjectURL(res)
|
||||
saveAs(res)
|
||||
}
|
||||
catch (error) {
|
||||
type = 'danger'
|
||||
}
|
||||
finally {
|
||||
type = 'success'
|
||||
loading = false
|
||||
}
|
||||
}
|
||||
|
||||
function download() {
|
||||
switch (typeof props.src) {
|
||||
case 'string':
|
||||
if (props.src.startsWith('http')) {
|
||||
url = props.src
|
||||
break
|
||||
}
|
||||
downloadByRequest(props.src)
|
||||
break
|
||||
case 'number':
|
||||
downloadByRequest(props.src)
|
||||
break
|
||||
case 'object':
|
||||
if (typeof props.src?.url === 'string')
|
||||
downloadByRequest(props.src.url)
|
||||
break
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
tryOnUnmounted(() => {
|
||||
if (url.startsWith('blob:')) {
|
||||
// revoke object URL after use to avoid memory leak.
|
||||
URL.revokeObjectURL(url)
|
||||
}
|
||||
})
|
||||
</script>
|
Reference in New Issue
Block a user