为了满足上传文件的样式各种,使用插槽的方式封装上传组件
组件代码
<template>
<a-upload v-model:file-list="fileList" name="file" :show-upload-list="false" :action="baseApiUrl"
:before-upload="beforeUpload" @change="handleChange" :accept="props.accept">
<slot></slot>
</a-upload>
</template>
<script lang="ts" setup>
import { ref } from 'vue';
import { message } from 'ant-design-vue';
import type { UploadChangeParam } from 'ant-design-vue';
interface Props {
accept: string, // 上传文件的格式
type: string // 是了在一个页面引用多个组件作的区分
}
const props = defineProps<Props>()
const baseApiUrl = `${import.meta.env.VITE_BASE_URL}file/upload`
const fileList = ref([]);
const $emit = defineEmits(["uploadLoad", "uploadDone"]) // 父组件上传成功,以及上传中的事件。
const handleChange = (info: UploadChangeParam) => {
if (info.file.status === 'uploading') {
$emit("uploadLoad", true, props.type)
return;
}
if (info.file.status === 'done') {
$emit("uploadLoad", false, props.type)
$emit("uploadDone", info.file.response, props.type)
}
if (info.file.status === 'error') {
$emit("uploadLoad", false, props.type)
message.error('上传失败');
}
};
const beforeUpload = (file: any) => {
const isJpgOrPng = file.type === 'image/jpeg' || file.type === 'image/png';
if (!isJpgOrPng) {
message.error('请上传png、jpg、jpeg、svg格式图片');
}
const isLt2M = file.size / 1024 / 1024 < 2;
if (!isLt2M) {
message.error('图片大小不允许超过2MB!');
}
return isJpgOrPng && isLt2M;
};
</script>
<style scoped></style>
父组件使用
先引入
import AntdUploadFile from "@/components/antdUploadFile/index.vue"
<AntdUploadFile accept="" type="frontIdcard" @upload-load="onUploading"
@upload-done="onUploadDone">
<div>
<a-button :loading="loading">选择文件</a-button>
<span>未选择任何文件</span>
</div>
</AntdUploadFile>
// 增加按钮loading
const loading = ref<boolean>(false)
const onUploading = (value: boolean, type: string) => {
// 这里控制loading 的显示与否 type,是为了一个页面引用多少文件上传作的区分
console.log(value, type);
if (value) {
loading.value = true
} else {
loading.value = false
}
}
// 图片上传成功
const onUploadDone = (file: any, type: string) => {
// 文件上传成功后返回的文件信息 type,是为了一个页面引用多少文件上传作的区分
console.log(file, type);
}