Files
vue3/packages/upload-single-file/index.vue
2023-07-21 04:30:18 +08:00

118 lines
2.7 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!--
* @Author: zhaojinfeng 121016171@qq.com
* @Date: 2023-07-21 00:37:46
* @LastEditors: zhaojinfeng 121016171@qq.com
* @LastEditTime: 2023-07-21 04:02:43
* @FilePath: \vue3\packages\upload-single-file\index.vue
* @Description:
*
-->
<template>
<div v-loading="loading" @click="startUpload">
<slot v-if="modelValue" name="download" :loading="loading">
<DownloadLink :src="modelValue" :file-name="fileName" />
</slot>
<slot v-else name="upload" :loading="loading">
<el-button type="primary" plain :text="text">
点击上传
</el-button>
</slot>
</div>
</template>
<script lang="ts" setup name="ThUploadSingleFile">
import DownloadLink from '../download-link/index.vue'
const props = withDefaults(defineProps<{
/** 文件id */
modelValue?: string | number
/** 自动上传 */
autoUpload?: boolean
/** 可接受的文件类型 */
accept?: string
disabled?: boolean
/** 激活默认按钮的text属性 */
text?: boolean
/** 文件上传的请求函数 */
request?: (formData: FormData) => Promise<FileVO>
/** 自定义的上传文件名称,不带后缀名 */
fileName?: string
/** 最大上传大小单位Mb */
maxsize?: number
}>(), {
modelValue: '',
autoUpload: false,
accept: '',
disabled: false,
maxsize: 20,
text: false,
request: () => {
throw new Error('请定义接口请求函数')
},
})
const emit = defineEmits<{
(event: 'update:modelValue', id?: number): void
(event: 'onChange', file: File): void
(event: 'onSuccess', file: FileVO): void
(event: 'onError', error: Error): void
}>()
let loading = $ref(false)
const { open, files, onChange } = useFileDialog({
accept: props.accept,
reset: true,
})
function startUpload() {
if (!props.disabled)
open()
}
async function upload() {
const file = files.value?.item(0)
if (!file) {
const err = '请选择上传文件'
ElMessage.error(err)
emit('onError', new Error(err))
return
}
if (file.size > props.maxsize * 1024 * 1024) {
const err = `文件大小不能超过${props.maxsize}Mb`
ElMessage.error(err)
emit('onError', new Error(err))
return
}
loading = true
try {
const formData = new FormData()
formData.append('file', file)
if (props.fileName)
formData.append('name', props.fileName)
const res = await props.request(formData)
emit('update:modelValue', res.id)
emit('onSuccess', res)
}
catch (err: any) {
emit('onError', err)
}
finally {
loading = false
}
}
onChange((param) => {
const file = param.item(0)
emit('onChange', file)
if (props.autoUpload)
upload()
})
watch(() => props.autoUpload,
(autoupload) => {
if (autoupload)
upload()
})
</script>