<template>
<a-upload
v-model:file-list="fileList"
name="avatar"
list-type="picture-card"
class="avatar-uploader"
:show-upload-list="false"
:before-upload="beforeUpload">
<img
v-if="imageUrl"
:src="imageUrl"
alt="avatar" />
<div v-else>
<plus-outlined></plus-outlined>
<div class="ant-upload-text">上传</div>
</div>
</a-upload>
<a-button @click="handleUpload"> 开始上传 </a-button>
</template>
<script lang="ts" setup>
import { PlusOutlined, LoadingOutlined } from '@ant-design/icons-vue';
import { message } from 'ant-design-vue';
import { ref } from 'vue';
const imageUrl = ref<string>('');
/**
* 图片转base64
*/
const getBase64 = (img, callback: (base64Url: string) => void) => {
const reader = new FileReader();
reader.addEventListener('load', () => callback(reader.result as string));
reader.readAsDataURL(img);
};
/**
* 上传文件之前的钩子 (可以恒返回false 从而手动上传)
* @param file 上传的文件
* @returns 布尔值或者Promise对象 若返回 false 则停止上传
*/
let fileList:any = ref(null);
const beforeUpload = (file) => {
const isJpgOrPng = file.type === 'image/jpeg' || file.type === 'image/png';
if (!isJpgOrPng) {
message.error('只能上传图片文件!');
}
const isLt2M = file.size / 1024 / 1024 < 2;
if (!isLt2M) {
message.error('头像图片不能超过 2MB!');
}
// 用于选择图片文件后本地实时预览
getBase64(file, (base64Url: string) => {
imageUrl.value = base64Url;
});
fileList.value = [file];
return false;
// return isJpgOrPng && isLt2M;
};
/**
* 手动图片上传
*/
const handleUpload = async () => {
const formData = new FormData();
formData.append('files', fileList.value[0]);
await api.curriculum.uploadFile.request(fileList.value[0]);
fileList.value = [];
message.success('上传成功');
};
</script>
<style>
.avatar-uploader > .ant-upload {
width: 128px;
height: 128px;
}
.ant-upload-select-picture-card i {
font-size: 32px;
color: #999;
}
.ant-upload-select-picture-card .ant-upload-text {
margin-top: 8px;
color: #666;
}
</style>
如果是手动上传的话action不用要 那个是提供给自动上传的url
change事件 也不再需要 因为那个是基于action请求状态触发,手动上传的时候 所有的逻辑均可在beforeUpdate中 编写