web技术分享| 图片上传与图片裁剪结合 vue3
需求:
-
上传的图片限制长宽相同; 只能上传图片; 图片大小限制 500k 当前项目仅需要上传的图片信息
项目组件使用
裁剪:vue-cropper
import "vue-cropper/dist/index.css"; import { VueCropper } from "vue-cropper";
上传: Upload 上传(element plus 组件)
实现理论:
- 通过组件 Upload 进行图片上传前校验方法判断是否需要裁剪、是否是图片、是否超过大小限制;
- 裁剪后的图片限制大小;
- 上传的图片信息暴漏出组件;
组件调用
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, }); };