<docs> --- order: 1 title: zh-CN: 用户头像 en-US: Avatar --- ## zh-CN 点击上传用户头像,并使用 `beforeUpload` 限制用户上传的图片格式和大小。 > `beforeUpload` 的返回值可以是一个 Promise 以支持异步处理,如服务端校验等:[示例](http://react-component.github.io/upload/examples/beforeUpload.html)。 ## en-US Click to upload user's avatar, and validate size and format of picture with `beforeUpload`. > The return value of function `beforeUpload` can be a Promise to check asynchronously. [demo](http://react-component.github.io/upload/examples/beforeUpload.html) </docs> <template> <a-upload v-model:file-list="fileList" name="avatar" list-type="picture-card" class="avatar-uploader" :show-upload-list="false" action="https://www.mocky.io/v2/5cc8019d300000980a055e76" :before-upload="beforeUpload" @change="handleChange" > <img v-if="imageUrl" :src="imageUrl" alt="avatar" /> <div v-else> <loading-outlined v-if="loading"></loading-outlined> <plus-outlined v-else></plus-outlined> <div class="ant-upload-text">Upload</div> </div> </a-upload> </template> <script lang="ts"> import { PlusOutlined, LoadingOutlined } from '@ant-design/icons-vue'; import { message } from 'ant-design-vue'; import { defineComponent, ref } from 'vue'; interface FileItem { uid: string; name?: string; status?: string; response?: string; url?: string; type?: string; size: number; originFileObj: any; } interface FileInfo { file: FileItem; fileList: FileItem[]; } function getBase64(img: Blob, callback: (base64Url: string) => void) { const reader = new FileReader(); reader.addEventListener('load', () => callback(reader.result as string)); reader.readAsDataURL(img); } export default defineComponent({ components: { LoadingOutlined, PlusOutlined, }, setup() { const fileList = ref([]); const loading = ref<boolean>(false); const imageUrl = ref<string>(''); const handleChange = (info: FileInfo) => { if (info.file.status === 'uploading') { loading.value = true; return; } if (info.file.status === 'done') { // Get this url from response in real world. getBase64(info.file.originFileObj, (base64Url: string) => { imageUrl.value = base64Url; loading.value = false; }); } if (info.file.status === 'error') { loading.value = false; message.error('upload error'); } }; const beforeUpload = (file: FileItem) => { const isJpgOrPng = file.type === 'image/jpeg' || file.type === 'image/png'; if (!isJpgOrPng) { message.error('You can only upload JPG file!'); } const isLt2M = file.size / 1024 / 1024 < 2; if (!isLt2M) { message.error('Image must smaller than 2MB!'); } return isJpgOrPng && isLt2M; }; return { fileList, loading, imageUrl, handleChange, beforeUpload, }; }, }); </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>