vue3 - 最新详细实现头像上传并裁剪功能,用户上传头像裁剪圆形并上传到服务器教程,可搭配element plus或ant design vue组件库,支持头像预览、完美对接服务端接口

要实现头像上传并裁剪的功能,可以使用以下步骤:

  1. 安装依赖:首先,你需要安装一些依赖。你可以选择使用 Element Plus 或 Ant Design Vue 组件库,具体选择哪个取决于你的需求。你还需要安装其他一些依赖,如 axios(用于发送请求到服务器)和 vue-cropper(用于裁剪头像)。

    使用 Element Plus 组件库的话,可以通过以下命令进行安装:

    npm install element-plus axios vue-cropper
    

    使用 Ant Design Vue 组件库的话,可以通过以下命令进行安装:

    npm install ant-design-vue axios vue-cropper
    

  2. 创建上传组件:创建一个头像上传组件,其中包含一个上传按钮和一个预览区域。根据你选择的组件库,可以使用 el-upload(Element Plus)或 a-upload(Ant Design Vue)组件来实现上传功能。使用 img 标签来预览头像。

    对于 Element Plus 组件库,上传组件可以如下所示:

    <template>
      <el-upload
        action="your-upload-api-url"
        :before-upload="beforeUpload"
        :on-success="onSuccess">
        <img v-if="imageUrl" :src="imageUrl" alt="Avatar" style="width: 120px; height: 120px; border-radius: 50%">
        <i v-else class="el-icon-plus avatar-uploader-icon"></i>
      </el-upload>
    </template>
    
    <script>
    export default {
      data() {
        return {
          imageUrl: '',
        };
      },
      methods: {
        beforeUpload(file) {
          const isJPG = file.type === 'image/jpeg';
          const isPNG = file.type === 'image/png';
          const isLt2M = file.size / 1024 / 1024 < 2;
    
          if (!isJPG && !isPNG) {
            this.$message.error('只支持上传 JPG 和 PNG 格式的图片');
          }
          if (!isLt2M) {
            this.$message.error('图片大小不能超过 2MB');
          }
    
          return (isJPG || isPNG) && isLt2M;
        },
        onSuccess(response) {
          this.imageUrl = response.url;
        },
      },
    };
    </script>
    

    对于 Ant Design Vue 组件库,上传组件可以如下所示:

    <template>
      <a-upload
        action="your-upload-api-url"
        :before-upload="beforeUpload"
        :custom-request="customRequest"
        :transform-file="transformFile">
        <img v-if="imageUrl" :src="imageUrl" alt="Avatar" style="width: 120px; height: 120px; border-radius: 50%">
        <a-icon v-else type="plus" class="avatar-uploader-trigger"></a-icon>
      </a-upload>
    </template>
    
    <script>
    import { message } from 'ant-design-vue';
    
    export default {
      data() {
        return {
          imageUrl: '',
        };
      },
      methods: {
        beforeUpload(file) {
          const isJPG = file.type === 'image/jpeg';
          const isPNG = file.type === 'image/png';
          const isLt2M = file.size / 1024 / 1024 < 2;
    
          if (!isJPG && !isPNG) {
            message.error('只支持上传 JPG 和 PNG 格式的图片');
          }
          if (!isLt2M) {
            message.error('图片大小不能超过 2MB');
          }
    
          return (isJPG || isPNG) && isLt2M;
        },
        customRequest({ file }) {
          const formData = new FormData();
          formData.append('file', file);
    
          axios.post('your-upload-api-url', formData)
            .then(response => {
              this.imageUrl = response.data.url;
            })
            .catch(error => {
              console.log(error);
              message.error('上传失败');
            });
        },
        transformFile(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');
                const ctx = canvas.getContext('2d');
                ctx.clearRect(0, 0, canvas.width, canvas.height);
                canvas.width = img.width;
                canvas.height = img.height;
                ctx.drawImage(img, 0, 0, img.width, img.height);
                canvas.toBlob(blob => {
                  resolve(blob);
                }, 'image/jpeg', 0.8);
              };
            };
          });
        },
      },
    };
    </script>
    

    以上代码中的 your-upload-api-url 需要替换为你的上传接口地址。

  3. 添加裁剪功能:为了实现头像裁剪功能,你可以使用 vue-cropper 组件。首先,安装该组件:

    npm install vue-cropper
    

    接下来,修改上传组件,添加一个裁剪按钮和一个裁剪区域:

    <template>
      <el-upload
        action="your-upload-api-url"
        :before-upload="beforeUpload"
        :on-success="onSuccess">
        <div v-if="!imageUrl" class="avatar-uploader">
          <i class="el-icon-plus avatar-uploader-icon"></i>
        </div>
        <div v-else class="avatar-container">
          <img :src="imageUrl" alt="Avatar" class="avatar">
          <a-button type="primary" @click="showCropper">裁剪</a-button>
        </div>
      </el-upload>
    
      <div v-show="showCropper" class="cropper-wrapper">
        <vue-cropper
          ref="cropper"
          :src="imageUrl"
          :auto-crop="true"
          :auto-zoom="true"
          :output-type="'png'"
          :output-quality="1"
          :fixed-box="true"
          :fixed-number="[1, 1]"
          :can-move="true"
          :can-move-box="true"
          :drag-mode="'move'"
          :modal="true"
          :preview=".cropper-preview"
          :view-mode="2"
          :center-box="true"
          :center-radius="1"
          :guides="false"
          :background="'#ffffff'"
          :zoom-step=".1"
          :rect-color="'#ff0000'"
          @crop-upload="cropUpload"
          @close="closeCropper">
        </vue-cropper>
      </div>
    </template>
    
    <script>
    import { ref } from 'vue';
    import { message } from 'element-plus'; //或者import { message } from 'ant-design-vue';
    
    export default {
      setup() {
        const showCropper = ref(false);
    
        return {
          showCropper,
        };
      },
      data() {
        return {
          imageUrl: '',
        };
      },
      methods: {
        beforeUpload(file) {
          const isJPG = file.type === 'image/jpeg';
          const isPNG = file.type === 'image/png';
          const isLt2M = file.size / 1024 / 1024 < 2;
    
          if (!isJPG && !isPNG) {
            this.$message.error('只支持上传 JPG 和 PNG 格式的图片');
          }
          if (!isLt2M) {
            this.$message.error('图片大小不能超过 2MB');
          }
    
          return (isJPG || isPNG) && isLt2M;
        },
        onSuccess(response) {
          this.imageUrl = response.url;
        },
        showCropper() {
          this.showCropper = true;
        },
        closeCropper() {
          this.showCropper = false;
        },
        cropUpload(dataUrl) {
          const blob = this.dataURLtoBlob(dataUrl);
          const formData = new FormData();
          formData.append('file', blob);
    
          axios.post('your-upload-api-url', formData)
            .then(response => {
              this.imageUrl = response.data.url;
              this.closeCropper();
            })
            .catch(error => {
              console.log(error);
              message.error('上传失败');
            });
        },
        dataURLtoBlob(dataURL) {
          const arr = dataURL.split(',');
          const mime = arr[0].match(/:(.*?);/)[1];
          const bstr = atob(arr[1]);
          let n = bstr.length;
          const u8arr = new Uint8Array(n);
          while (n--) {
            u8arr[n] = bstr.charCodeAt(n);
          }
          return new Blob([u8arr], { type: mime });
        },
      },
    };
    </script>
    
    <style>
    .avatar-uploader {
      border: 1px dashed #d9d9d9;
      border-radius: 6px;
      cursor: pointer;
      overflow: hidden;
      position: relative;
    

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值