web技术分享| 图片上传与图片裁剪结合 vue3

需求:

    上传的图片限制长宽相同; 只能上传图片; 图片大小限制 500k 当前项目仅需要上传的图片信息

项目组件使用

裁剪:vue-cropper

import "vue-cropper/dist/index.css";
import {
          
    VueCropper } from "vue-cropper";

上传: Upload 上传(element plus 组件)

实现理论:

  1. 通过组件 Upload 进行图片上传前校验方法判断是否需要裁剪、是否是图片、是否超过大小限制;
  2. 裁剪后的图片限制大小;
  3. 上传的图片信息暴漏出组件;

组件调用

img-url 默认预览的图片 @img-upload 上传所需的最终图片

代码实现

页面

裁剪时弹窗显示

<!-- 上传 -->
  <el-upload
    class="uploader_cutsom"
    action=""
    :show-file-list="false"
    :accept="imgUpload.imgBmp"
    :http-request="updataImg"
    :before-upload="beforUpload"
  >
    <div v-if="imgUpload.imageUrl" class="w-full h-full relative">
      <img class="w-full h-full" :src="imgUpload.imageUrl" />
      <!-- 删除 -->
      <div
        @click="clearImg"
        class="absolute top-0 right-0 w-8 h-8 rounded flex items-center justify-center bg-black bg-opacity-30 text-white text-base z-20 cursor-pointer"
      >
        <i class="iconfont icon-shanchu"></i>
      </div>
    </div>

    <div v-else class="uploader_cutsom_default">
      <p>从你的计算机中</p>
      <p class="uploader_cutsom_default_button">选择文件</p>
    </div>
  </el-upload>
  <!-- 裁剪 -->
  <el-dialog
    v-model="imgUpload.dialogCropping"
    custom-class="dialog_custom"
    title="裁剪图片"
    append-to-body
    :close-on-press-escape="false"
    :show-close="false"
    :close-on-click-modal="false"
  >
    <div>
      <div class="h-96 w-full">
        <vueCropper
          ref="cropper"
          class="vue_cropper_custom"
          :img="imgCropping.imageUrl"
          :outputType="imgCropping.outputType"
          :autoCrop="imgCropping.autoCrop"
          :autoCropWidth="imgCropping.autoCropWidth"
          :autoCropHeight="imgCropping.autoCropHeight"
          :fixed="imgCropping.fixed"
          :fixedNumber="imgCropping.fixedNumber"
          :centerBox="imgCropping.centerBox"
          :full="imgCropping.full"
        ></vueCropper>
      </div>
    </div>
    <template #footer>
      <el-button v-focus @click="handleCropping($refs.cropper, false)">
        取消
      </el-button>
      <el-button
        v-focus
        type="primary"
        @click="handleCropping($refs.cropper, true)"
      >
        确定
      </el-button>
    </template>
  </el-dialog>

逻辑

图片相关方法封装

/** 查询图片大小 */
export const imgSize = (file: any) => {
          
   
  return new Promise((resolve, reject) => {
          
   
    let reader = new FileReader();
    reader.readAsDataURL(file);
    reader.onload = () => {
          
   
      // 让页面中的img标签的src指向读取的路径
      let img = new Image();
      img.src = reader.result as string;
      if (img.complete) {
          
   
        // 如果存在浏览器缓存中
        if (img.width / img.height !== 1) {
          
   
          resolve(false);
        } else {
          
   
          resolve(true);
        }
      } else {
          
   
        img.onload = () => {
          
   
          if (img.width / img.height !== 1) {
          
   
            resolve(false);
          } else {
          
   
            resolve(true);
          }
        };
      }
    };
  });
};

/**
 * 文件格式转换
 * @description blobToFile
 * @param {Blob} blob
 * @param {String} fileName
 */
export const blobToFile = (blob: any, fileName: string) => {
          
   
  return new window.File([blob], fileName, {
          
   
    type: blob.type,
  });
};
经验分享 程序员 微信小程序 职场和发展