在现代Web应用开发中,用户界面的交互性和美观性至关重要。特别是对于个人资料页面,一个简洁且功能完备的头像上传组件可以显著提升用户体验。本文将介绍如何使用React结合Ant Design来构建一个支持图片预览、水印添加以及上传进度提示的头像上传组件。

技术栈
  • React: 负责组件化开发。
  • Ant Design: 提供了丰富的UI组件库。
  • FileReader API: 用于读取文件内容并转换为Base64字符串。
功能亮点
  1. 图片格式验证: 只允许上传JPEG或PNG格式的图片。
  2. 大小限制: 图片大小不得超过2MB。
  3. 上传进度指示: 显示上传状态(如加载中、上传完成)。
  4. 图片预览: 实时预览已选择的图片。
  5. 水印添加: 在上传前自动给图片添加指定文字水印
代码解析

首先,我们导入必要的React Hook以及Ant Design提供的组件:

import React, { useEffect, useState } from 'react';
import { LoadingOutlined, PlusOutlined, UploadOutlined } from '@ant-design/icons';
import { Flex, message, Upload, Avatar, List } from 'antd';
  • 1.
  • 2.
  • 3.


import React, { useEffect, useState } from 'react';
import { LoadingOutlined, PlusOutlined ,UploadOutlined } from '@ant-design/icons';
import { Flex, message, Upload, Avatar, List  } from 'antd';
 
const props = {
    action: 'http://xxx.xx.76.143:48080/admin-api/system/user/profile/update-avatar',
    listType: 'picture-circle',
    name:"avatarFile",
    headers: {
        'Authorization':'Bearer '+ localStorage.getItem('token'),
        'tenant-id': '1'
    },
    beforeUpload(file) {
        return new Promise((resolve) => {
        const reader = new FileReader();
        reader.readAsDataURL(file);
        reader.onload = () => {
            const img = document.createElement('img');
            img.src = reader.result;
            img.onload = () => {
            const canvas = document.createElement('canvas');
            canvas.width = img.naturalWidth;
            canvas.height = img.naturalHeight;
            const ctx = canvas.getContext('2d');
            ctx.drawImage(img, 0, 0);
            ctx.fillStyle = '#fff';
            ctx.textBaseline = 'middle';
            ctx.font = '23px Arial';
            ctx.fillText('版权归属woods', 20, 20);
            canvas.toBlob((result) => resolve(result));
            };
        };
        });
    },
};
const beforeUpload = (file) => {
  const isJpgOrPng = file.type === 'image/jpeg' || file.type === 'image/png';
  if (!isJpgOrPng) {
    message.error('You can only upload JPG/PNG file!');
  }
  const isLt2M = file.size / 1024 / 1024 < 2;
  if (!isLt2M) {
    message.error('Image must smaller than 2MB!');
  }
  return isJpgOrPng && isLt2M;
};
const UserInfo = (userData) => {
  const [loading, setLoading] = useState(false);
  const [imageUrl, setImageUrl] = useState('');

    useEffect(() => {
       setImageUrl(userData.data.avatar) 
    }, [userData])
  const handleChange = (info) => {
    if (info.file.status === 'uploading') {
      setLoading(true);
      return;
    }
    if (info.file.status === 'done') {
      
    }
  };
  const uploadButton = (
    <button
      style={{
        border: 0,
        background: 'none',
      }}
      type="button"
    >
      {loading ? <LoadingOutlined /> : <PlusOutlined />}
      <div
        style={{
          marginTop: 8,
        }}
      >
        Upload
      </div>
    </button>
  );
  return (
    <div>
        <Flex gap="middle" wrap>
        
        <Upload
            name="avatarFile"
            listType="picture-circle"
            className="avatar-uploader"
            showUploadList={false}
            action="http://xxx.xx.76.143:48080/admin-api/system/user/profile/update-avatar"
            beforeUpload={beforeUpload}
            onChange={handleChange}
            headers={{
            'Authorization':'Bearer '+ localStorage.getItem('token'),
            'tenant-id': '1'
            }}
        >
            {imageUrl ? (
            <img  src={imageUrl} alt="avatar" style={{ width: '100%', }} />
            ) : ( uploadButton )}
        </Upload>

        <Upload {...props}>
            {imageUrl ? (
            <img  src={imageUrl} alt="avatar" style={{ width: '100%', }} />
            ) : ( uploadButton )}
            </Upload>
        </Flex>
    </div>
  );
};
export default UserInfo;
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.
  • 65.
  • 66.
  • 67.
  • 68.
  • 69.
  • 70.
  • 71.
  • 72.
  • 73.
  • 74.
  • 75.
  • 76.
  • 77.
  • 78.
  • 79.
  • 80.
  • 81.
  • 82.
  • 83.
  • 84.
  • 85.
  • 86.
  • 87.
  • 88.
  • 89.
  • 90.
  • 91.
  • 92.
  • 93.
  • 94.
  • 95.
  • 96.
  • 97.
  • 98.
  • 99.
  • 100.
  • 101.
  • 102.
  • 103.
  • 104.
  • 105.
  • 106.
  • 107.
  • 108.
  • 109.
  • 110.
  • 111.
  • 112.

两种上传文件写法,都能上传图片

React和Ant Design实现图片上传功能_上传