页面使用:
<template>
<div>
<a-form-item :field="item.value" :label="item.label" :rules="item.rules">
<uploadFiles :limit="5" @onsuccess="storePhotosUploadOnsuccess" :fileList="storePhotosList"> </uploadFiles>
</a-form-item>
</div>
</template>
<script setup lang="ts">
import { ref, reactive, watch, computed, onMounted, onBeforeUnmount, getCurrentInstance } from 'vue'
import uploadFiles from '@/components/uploadFile/index.vue'
const storePhotosList = ref([])
const storePhotosUploadOnsuccess = (files, filesStr) => {
storePhotosList.value = files
formData.form.storePhotos = filesStr
}
</script>
组件:
<template>
<div ref="downloadDom">
<a-upload
v-if="type == 'add' || type == 'edit'"
:action="uploadUrl"
:headers="headers"
@success="uploadSuccess"
:on-before-remove="beforeRemove"
name="files"
:image-preview="imagePreview"
@before-upload="beforeUpload"
:limit="limit"
:accept="accept"
:file-list="reactiveData.fileList"
:default-file-list="reactiveData.fileList"
:show-upload-button="showUploadBtn"
:show-remove-button="showRemoveBtn"
:download="true"
:showFileList="showFileList"
:fileSize="fileSize"
:list-type="listType"
>
<template #upload-button v-if="custom">
<slot name="button"></slot>
</template>
</a-upload>
<div v-else>
<template v-if="reactiveData.fileList && reactiveData.fileList.length > 0">
<a-link
style="display: block"
v-for="(file, index) in reactiveData.fileList"
:download="file.name.substring(file.name.lastIndexOf('/') + 1)"
:key="index"
:href="file.url"
:hoverable="false"
>
<a-space>
<icon-file />
{{ file.name.substring(file.name.lastIndexOf('/') + 1) }}
</a-space>
</a-link>
</template>
<template v-else> 暂无 </template>
</div>
</div>
</template>
<script lang="ts" setup>
import { ref, reactive, computed, defineEmits, defineProps, defineExpose, watch, toRaw, getCurrentInstance, onMounted, nextTick } from 'vue'
import { Message, Modal } from '@arco-design/web-vue'
import useLoading from '@/hooks/loading'
const { loading, setLoading } = useLoading()
import { getToken } from '@/utils/auth'
const emit = defineEmits(['onsuccess', 'beforeUpload'])
const uploadUrl = ref("");
uploadUrl.value=import.meta.env.VITE_DOWNLOAD_HOST+'/file/upload';
const props = defineProps({
/**
* @params 文件列表数据
*/
fileList: {
type: Array,
default: [],
},
/**
* @params 接收的上传文件类型
*/
accept: {
type: String,
default: '.png,.jpg,.jpeg',
},
/**
* @params 上传文件个数
*/
limit: {
type: Number,
default: 1,
},
/**
* @params 图片预览功能是否展示
*/
imagePreview: {
type: Boolean,
default: true,
},
/**
* @params 上传图标是否展示
*/
showUploadBtn: {
type: Boolean,
default: true,
},
/**
* @params 删除图标是否展示
*/
showRemoveBtn: {
type: Boolean,
default: true,
},
/**
* @params edit add新增编辑可以上传 view只是查看
*/
type: {
type: String,
default: 'add',
},
/**
* @params 上传图片大小最大多少M
*/
fileSize: {
type: Number,
default: 5,
},
/**
* @params 图片列表类型
*/
listType: {
type: String,
default: 'picture-card',
},
/**
* @params 自定义上传图标的插槽名
*/
slotName: String,
custom: {
type: Boolean,
default: false,
},
/**
* @params 是否显示文件列表
*/
showFileList: {
type: Boolean,
default: true,
},
})
const reactiveData = reactive({
fileList: [],
})
//监听
watch(
() => props.fileList,
(val) => {
reactiveData.fileList = props.fileList
nextTick(() => {
addClickEvent()
})
},
{ deep: true, immediate: true }
)
/*******upload Header********/
const headers = computed(() => {
const token = getToken()
return {
client: '1', // 客户端类型 1 web端 2 移动端
Authorization: `${token}`,
}
})
/* 删除 */
const beforeRemove = (file) => {
let index = reactiveData.fileList.findIndex((item) => item.id === file.id)
reactiveData.fileList.splice(index, 1)
emit('onsuccess', reactiveData.fileList)
}
/* 上传前文件大小限制提醒 */
const beforeUpload = (file) => {
const isLtM = file.size / 1024 / 1024 < props.fileSize
if (!isLtM) {
Message.error('文件不能超过M' + props.fileSize + 'M')
}
emit('beforeUpload')
return isLtM
}
/* 上传成功 */
const uploadSuccess = (file) => {
const res = file.response
if (res?.data) {
let data = res.data
let imgPath = data[0] ? data[0].filePath : ''
let fileId = data[0] ? data[0].fileId : ''
const obj = {
name: file.name,
id: fileId,
url: 'http://10.60.0.44:8950' + imgPath,
imgPath: imgPath,
}
reactiveData.fileList.push(obj)
let filesStr = ''
if (reactiveData.fileList && reactiveData.fileList.length) {
const imgpathArr = reactiveData.fileList.map((item) => {
return item.imgPath
})
filesStr=imgpathArr.join(',')
console.log(filesStr);
}
emit('onsuccess', reactiveData.fileList,filesStr)
}
}
const { proxy } = getCurrentInstance()
const addClickEvent = () => {
if (!proxy.$refs['downloadDom']) {
return
}
let downloadDom = proxy.$refs['downloadDom'].getElementsByTagName('a')
let links = Object.values(downloadDom)
links.forEach((link) => {
link.onclick = (e) => {
e.preventDefault()
downloadFile(link.href + '?secret=' + keyId.value, link.download)
}
})
}
//文件下载
const downloadFile = (url: any, fileName: any) => {
fetch(url).then((res) => {
res.blob().then((blob) => {
const blobUrl = window.URL.createObjectURL(blob)
// 这里的文件名根据实际情况从响应头或者url里获取
const filename = fileName
const a = document.createElement('a')
a.href = blobUrl
a.download = filename
a.click()
window.URL.revokeObjectURL(blobUrl)
})
})
}
</script>
<style lang="less" scoped></style>
/*文件下载方法*/
const downloadFile = (url: any, fileName: any) => {
fetch(url).then((res) => {
res.blob().then((blob) => {
const blobUrl = window.URL.createObjectURL(blob)
// 这里的文件名根据实际情况从响应头或者url里获取
const filename = fileName
const a = document.createElement('a')
a.href = blobUrl
a.download = filename
a.click()
window.URL.revokeObjectURL(blobUrl)
})
})
}