113 lines
2.5 KiB
Vue
113 lines
2.5 KiB
Vue
<!--
|
||
* @Author: zhaojinfeng 121016171@qq.com
|
||
* @Date: 2023-07-21 00:37:46
|
||
* @LastEditors: zhaojinfeng 121016171@qq.com
|
||
* @LastEditTime: 2023-07-21 03:31:04
|
||
* @FilePath: \vue3\packages\upload-single-file\index.vue
|
||
* @Description:
|
||
*
|
||
-->
|
||
<template>
|
||
<div v-loading="loading" @click="startUpload">
|
||
<slot :loading="loading">
|
||
<el-button type="primary" plain :text="text">
|
||
点击上传
|
||
</el-button>
|
||
</slot>
|
||
</div>
|
||
</template>
|
||
|
||
<script lang="ts" setup name="ThUploadSingleFile">
|
||
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>
|