1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > Ant Design 结合 vue-cropper 实现上传图片裁剪功能

Ant Design 结合 vue-cropper 实现上传图片裁剪功能

时间:2022-03-27 13:59:25

相关推荐

Ant Design 结合 vue-cropper 实现上传图片裁剪功能

1. 引入 vue-cropper 第三方插件

npm install vue-cropperyarn add vue-cropper

2. 在 main.js 全局进入

import VueCropper from 'vue-cropper'Vue.use(VueCropper)

3. 封装成组件

3.1 上传组件

<template><div class="ant-upload-preview"><div class="avatatImg"><a-uploadname="avatar"listType="picture-card":showUploadList="false":beforeUpload="beforeUpload":customRequest="function () {}"@change="handleChange"accept="image/png,image/jpeg"><img class="upload_img" v-if="imageUrl" :src="imageUrl" alt="avatar" /><div v-else><a-icon :type="loading ? 'loading' : 'plus'" /><div class="ant-upload-text">上传图片</div></div></a-upload><div class="text"><div>{{avatarTextTop }}</div><div>{{avatarTextBottom }}</div></div></div><!-- 引入裁剪组件 --><CropperModalref="CropperModal":imgType="imgType":fileName="fileName":cropperMode="cropperMode"@cropper-no="handleCropperClose"@cropper-ok="handleCropperSuccess"></CropperModal></div></template><script>import {message } from "ant-design-vue";import CropperModal from "./CropperModal";export default {components: {CropperModal },props: {//图片裁切配置options: {type: Object,default: function () {return {autoCrop: true, //是否默认生成截图框autoCropWidth: 1029, //默认生成截图框宽度autoCropHeight: 480, //默认生成截图框高度fixedBox: true, //是否固定截图框大小 不允许改变previewsCircle: false, //预览图是否是原圆形title: "修改图片",};},},avatarTextTop: {type: String,default: "推荐使用160*160px,JPG.PNG.JPEG格式",},avatarTextBottom: {type: String,default: "图片小于1M",},// 上传图片的大小,单位MimgSize: {type: Number,default: 2,},//图片存储在oss上的上级目录名imgType: {type: String,default: "",},// 图片地址imageUrl: {type: String,default: "",},},data() {return {fileName: "", // 文件名loading: false,isStopRun: false,cropperMode: 'contain' // 图片渲染方式};},methods: {//从本地选择文件handleChange(info) {if (!info.file.status) {this.loading = false;} else {this.loading = true;}this.fileName = info.file.name;if (this.isStopRun) {return;}const {options } = this;this.getBase64(info.file.originFileObj, (imageUrl) => {const target = Object.assign({}, options, {img: imageUrl,});this.$refs.CropperModal.edit(target);});},// 上传之前 格式与大小校验beforeUpload(file) {this.$emit("avatarLoadingFn", true);const isJpgOrPng =file.type === "image/jpeg" || file.type === "image/png";if (!isJpgOrPng) {message.error("不能上传其他类型的图片");}// 获取上传图片尺寸var reader = new FileReader();reader.readAsDataURL(file);reader.onload = () => {var img = new Image()img.src = reader.resultimg.onload = () => {// 1、先根据图片裁剪的尺寸if (this.options.autoCropWidth > this.options.autoCropHeight) {// 2、再根据上传图片尺寸this.cropperMode = this.options.autoCropWidth + 'px auto'} else {if (img.width >= img.height) {this.cropperMode = 'auto ' + this.options.autoCropHeight + 'px'} else {this.cropperMode = this.options.autoCropWidth + 'px auto'}}}}return isJpgOrPng;},//获取服务器返回的地址handleCropperSuccess(data) {//将返回的数据回显this.loading = false;this.$emit("avatarfn", data);},// 取消上传handleCropperClose() {this.loading = false;},getBase64(img, callback) {if (img) {const reader = new FileReader();reader.addEventListener("load", () => callback(reader.result));reader.readAsDataURL(img);}},},};</script><style lang="less" scoped>.avatar-upload-wrapper {height: 180px;width: 100%;}.ant-upload-preview {background-color: #fff;.avatar-uploader > .ant-upload {width: 128px;height: 128px;}.ant-upload-select-picture-card i {font-size: 32px;color: #999;}.upload_img {width: 100%;}.ant-upload-select-picture-card .ant-upload-text {margin-top: 8px;color: #666;}}.ant-upload-picture-card-wrapper {width: auto;}.avatar-uploader > .ant-upload {width: 128px;height: 128px;}.avatatImg {// width: 100%;display: flex;align-items: center;.text {margin-left: 20px;div {line-height: 30px !important;font-weight: 600;}}}</style>

3.2 裁剪组件

<template><a-modal:visible="visible":title="options.title":maskClosable="false":confirmLoading="confirmLoading":width="1200"@cancel="cancelHandel"><a-row><a-col :xs="24" :md="24" :style="{ height: '600px' }"><vue-cropperref="cropper":img="options.img":info="true":autoCrop="options.autoCrop":autoCropWidth="options.autoCropWidth":autoCropHeight="options.autoCropHeight":fixedBox="options.fixedBox":mode="cropperMode"@realTime="realTime"></vue-cropper></a-col><!-- <a-col :xs="24" :md="12" :style="{ height: '250px' }"><div:class="options.previewsCircle? 'avatar-upload-preview': 'avatar-upload-preview_range'"><img :src="previews.url" :style="previews.img" /></div></a-col> --></a-row><template slot="footer"><a-button key="back" @click="cancelHandel">取消</a-button><a-buttonkey="submit"type="primary":loading="confirmLoading"@click="okHandel">保存</a-button></template></a-modal></template><script>import axios from "axios";import {domainName } from "@/config/index"; // 后台服务器的域名export default {props: {//图片存储在oss上的上级目录名imgType: {type: String,default: "",},fileName: {type: String, // 文件名default: "",},cropperMode: {// 图片渲染方式type: String,default: 'contain'}},data() {return {visible: false,img: null,confirmLoading: false,options: {img: "", //裁剪图片的地址autoCrop: true, //是否默认生成截图框autoCropWidth: 180, //默认生成截图框宽度autoCropHeight: 180, //默认生成截图框高度fixedBox: true, //是否固定截图框大小 不允许改变previewsCircle: false, //预览图是否是原圆形title: "修改图片",},previews: {},url: {upload: "/sys/common/saveToImgByStr",},};},methods: {edit(record) {const {options } = this;this.visible = true;this.options = Object.assign({}, options, record);},// 取消截图cancelHandel() {this.confirmLoading = false;this.visible = false;this.$emit("cropper-no");},// 确认截图okHandel() {const that = this;that.confirmLoading = true;// 获取截图的base64 数据this.$refs.cropper.getCropData((data) => {let file = this.dataURLtoFile(data, this.fileName);let formData = new window.FormData();formData.append("uploadFile", file);axios.post(`${domainName}/admin/files/upload/images`, formData).then((res) => {if (res.data.code == 200) {this.visible = false;this.confirmLoading = false;this.$emit("cropper-ok", res.data.data);}});});},//移动框的事件realTime(data) {this.previews = data;},// base 64 转成二进制文件流dataURLtoFile(dataurl, filename) {var arr = dataurl.split(","),mime = arr[0].match(/:(.*?);/)[1],bstr = atob(arr[1]),n = bstr.length,u8arr = new Uint8Array(n);while (n--) {u8arr[n] = bstr.charCodeAt(n);}return new File([u8arr], filename, {type: mime });},},};</script><style lang="less" scoped>.avatar-upload-preview_range,.avatar-upload-preview {position: absolute;top: 50%;transform: translate(50%, -50%);width: 100%;height: 100%;border-radius: 50%;box-shadow: 0 0 4px #ccc;overflow: hidden;img {background-color: red;height: 100%;}}.avatar-upload-preview_range {border-radius: 0;}</style>

4. 在页面中使用

4.1 HTML

<CropperUpload:imageUrl="form.coverUrl":options="coverOptions"@avatarfn="coverUrlFn"avatarTextTop="推荐使用174px*200px JPG.PNG.JPEG格式 图片小于1M"avatarTextBottom=""/>// imageurl --> 图片地址// options --> 截图配置项// coverUrlFn -- > 接收需要传递回后台的参数

4.2 options

export default {data(){return {coverOptions: {autoCrop: true, //是否默认生成截图框autoCropWidth: 174, //默认生成截图框宽度autoCropHeight: 200, //默认生成截图框高度fixedBox: true, //是否固定截图框大小 不允许改变previewsCircle: false, //预览图是否是原圆形title: "修改图片",},}}}

5. 效果图

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。