图片裁剪 cropper.js 上传组件封装 vue
//HTML cropper.js 文档地址: https://github.com/fengyuanchen/cropperjs/blob/master/README.md <template> <div class="container"> <div> <el-button size="small" plain icon="el-icon-plus" @click="uploadFuc" >点击上传</el-button > </div> <!-- <loading v-if="loadingFlag"></loading> --> <div class="defaultimg" v-if="!imgurl && isShowdefault">默认图</div> <div class="coropperImg" v-if="listImg" :style="styleObject"> <img :src="listImg" :width="imgWidth" :height="imgHeight" /> <span @click="deleteImg" v-if="isShowDelete">✕</span> </div> <div class="upload-file"> <el-dialog :visible.sync="dialogTableVisible" :title="title" :modal-append-to-body="false" :width="dialogWidth" > <div class="img-box"> <div class="upload-box" :style="styleObject"> <div class="upload"> <div v-if="!imgurl" class="upFileStyle"> <el-button size="small" @click="addFile" plain icon="el-icon-plus" >点击上传</el-button > <div slot="tip" class="el-upload__tip">{{ tips }}</div> <input type="file" style="display:none" ref="file" accept="image/*" @change="getFile($event)" /> </div> <img v-if="imgurl" :id="imageId" :src="imgurl" class="avatarImg" /> </div> <div v-if="imgurl" :class="['caropper', isDisable == true ? 'disabled' : '']" > <div @click="addFile" :class="['repeat-img', isDisable == true ? 'disabled' : '']" > 重新上传 </div> <input type="file" style="display:none" ref="file" accept="image/*" @change="getFile($event)" /> <div class="icon-font"> <div class="icon icon-jianqu" @click="narrowImg" /> <div class="icon icon-zengjia" @click="enlargeImg" /> <div class="icon icon-shuaxin" @click="refresh" /> </div> </div> </div><div class="imgPrew" :style="stylePrew"> <div v-if="imgurl" class="prewImg" /> <img v-else src alt /> <h5>预览</h5> <div /> </div> </div> <div slot="footer" class="dialog-footer"> <el-button size="small" plain @click="dialogVisibleCancel" >取 消</el-button > <el-button size="small" plain :class="['sure', imgurl ? '' : 'disabled']" @click="confirm" :loading="loadingFlag" >确 定</el-button > </div> </el-dialog> </div> </div> </template>//JS <script> export default { props: { title: { type: String, required: false, default: () => { return ""; } }, imageId: { type: String, required: false, default: () => { return ""; } }, listImgParent: { type: String, required: false, default: () => { return ""; } }, dialogWidth: { type: String, required: false, default: () => { return ""; } }, contentType: { type: String, required: false, default: () => { return ""; } }, tips: { type: String, required: false, default: () => { return ""; } }, proportion: { type: Number, required: false, default: () => { return ""; } }, imgWidth: { type: String, required: false, default: () => { return ""; } }, imgHeight: { type: String, required: false, default: () => { return ""; } }, prewWidth: { type: String, required: false, default: () => { return ""; } }, prewHeight: { type: String, required: false, default: () => { return ""; } }, sizeTips: { type: String, required: false, default: () => { return "图片大小不超1M"; } }, fileSize: { type: Number, required: false, default: () => { return 1048576; } }, isShowdefault: { type: Boolean, required: false, default: () => { return false; } }, isShowDelete: { type: Boolean, required: false, default: () => { return false; } } }, data() { return { dialogTableVisible: false, imgurl: "", uploadUrl: null, listImg: "", carImage: "", styleObject: { width: this.imgWidth, height: this.imgHeight }, stylePrew: { width: this.prewWidth, height: this.prewHeight }, fileName: "", loadingFlag: false, isDisable: false }; }, created() { this.loadImgSrc(); }, mounted() { //详情页面图片展示 if (this.listImgParent) { this.listImg = this.listImgParent; this.$emit("listentoChild", this.listImgParent); } }, methods: { //删除图片按钮 deleteImg() { this.listImg = ""; this.$emit("listentoChild", this.listImg); }, //动态插入Croppe. js 插件,做图片裁剪 loadImgSrc() { if (!document.getElementById("IMAGE_LINK_ID")) { let linkImage = document.createElement("link"); linkImage.id = "IMAGE_LINK_ID"; linkImage.type = "text/css"; linkImage.rel = "stylesheet"; linkImage.href = "//cdnjs.cloudflare.com/ajax/libs/cropperjs/1.4.3/cropper.min.css"; linkImage.onload = () => { let scriptImage = document.createElement("script"); scriptImage.id = "IMAGE_SCRIPT_ID"; scriptImage.type = "text/javascript"; scriptImage.src = "//cdnjs.cloudflare.com/ajax/libs/cropperjs/1.4.3/cropper.min.js"; document.body.appendChild(scriptImage); }; document.head.appendChild(linkImage); } }, //添加图片上传 addFile() { this.$refs.file.click(); }, //获取裁剪完成后url getFile(event) { if (this.carImage) { this.carImage.destroy(); } this.file = event.target.files[0]; const item = { name: this.file.name, size: this.file.size, file: this.file }; this.html5Reader(this.file, item); this.f = item; }, // 将图片文件转成BASE64格式 html5Reader(file, item) { let fileName = item.name .toLowerCase() .split(".") .splice(-1); this.fileName = fileName.join(""); const isJPG = file.type == "image/jpeg"; const isPNG = file.type == "image/png"; const isLt1M = file.size > this.fileSize; if (!isJPG && !isPNG) { this.$message.error("上传图片只能是 JPG 格式 或 png 格式!"); if (this.imgurl) { this.cuttingImg(); } return false; } if (isLt1M) { this.$message.error(this.sizeTips); if (this.imgurl) { this.cuttingImg(); } return false; } let _this = this; const reader = new FileReader(); reader.onload = e => { _this.imgurl = e.target.result; }; reader.readAsDataURL(file); this.$nextTick(() => { setTimeout(() => { this.cuttingImg(); }, 1000); }); }, //裁剪图片确定上传 confirm() { this.loadingFlag = true; this.isDisable = true; let cas = null; setTimeout(() => { cas = this.carImage.getCroppedCanvas().toDataURL("image/jpeg"); let formData = new FormData(); let uploadData = { contentType: this.contentType, project: "hooli" }; Object.assign(uploadData, this.$net.commonParams()); uploadData.signToken = this.$net.paramsSign( uploadData, this.$apis.api_common_files ); for (let key in uploadData) { formData.append(key, uploadData[key]); } let file = this.dataURLtoFile(cas, `imageName.${this.fileName}`); formData.append("files[]", file); axios .post(this.$apis.api_common_files, formData, { "Content-Type": "multipart/form-data" }) .then( res => { this.loadingFlag = false; this.isDisable = false; let data = res.data; if (parseInt(data.code) == 0) { let imgUrl = data.data.host + data.data.url; this.listImg = imgUrl; this.dialogTableVisible = false; this.$emit("listentoChild", imgUrl); } }, e => { this.loadingFlag = false; e && e.msg ? this.$message.error(e && e.msg) : this.$message.error("上传超时,请压缩图片后重试。"); } ); }, 100); }, //将base64转换为文件 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 }); }, dialogVisibleCancel() { this.loadingFlag = false; this.dialogTableVisible = false; }, uploadFuc() { this.dialogTableVisible = true; this.imgurl = ""; if (this.carImage) { this.carImage.destroy(); } }, cuttingImg() { let image = document.getElementById(this.imageId); this.carImage = new Cropper(image, { aspectRatio: this.proportion, viewMode: 1, crop() {}, preview: ".prewImg" }); }, refresh() { this.carImage.reset(); }, narrowImg() { this.carImage.zoom(-0.1); }, enlargeImg() { this.carImage.zoom(0.1); } } }; </script> //css <style> .container .el-dialog__header {padding: 10px 0 10px 10px !important; } .container .avatar-uploader .el-upload {border: 0; position: relative; left: 50%; top: 50%; transform: translate(-50%, -50%); } .container .el-button.is-plain:focus, .el-button.is-plain:hover {background: rgba(255, 255, 255, 1); border-radius: 4px; border: 1px solid; color: rgba(102, 102, 102, 1); } .container .el-upload__tip {font-family: PingFangSC-Regular; font-weight: 400; color: rgba(153, 153, 153, 1); padding: 0 50px; line-height: 23px; } .container .avatar-uploader-icon {font-size: 28px; color: #8c939d; width: 178px; height: 178px; line-height: 178px; text-align: center; } .container .avatarImg {width: 270px; height: 270px; } .container .dialog-footer button {width: 120px; height: 36px; line-height: 36px; background: rgba(249, 249, 249, 1); border-radius: 4px; border: 1px solid #cccccc; padding: 0; font-size: 14px; font-family: PingFangSC-Regular; font-weight: 400; color: rgba(102, 102, 102, 1); outline: none; } .container .dialog-footer .sure {background: rgba(255, 82, 61, 1); border-radius: 4px; border: 0; color: #fff; margin-left: 10px; } .container .el-dialog {width: 470px; } .container .el-dialog__footer {border-top: 1px solid rgba(238, 238, 238, 1); padding: 30px 0; margin-top: 30px; text-align: center; } .container .el-dialog__body {padding: 40px 20px; } </style><style lang="less" scoped> .container {.disabled { pointer-events: none; cursor: default; opacity: 0.6; } .defaultimg {font-size: 12px; line-height: 12px; margin: 24px 0 10px; } .coropperImg {margin-top: 10px; position: relative; span { width: 20px; height: 20px; display: inline-block; position: absolute; top: -27px; right: -22px; z-index: 10; cursor: pointer; } } #imageId {width: 110px; height: 100px; } .img-box {display: flex; justify-content: space-between; .upload-box { position: relative; .upload { border: 1px dashed #d9d9d9; border-radius: 2px; display: flex; flex-direction: column; overflow: hidden; width: 100%; height: 100%; background: rgba(249, 249, 249, 1); img { width: 100%; height: 100%; position: absolute; left: 0; top: 0; } .upFileStyle {position: relative; left: 50%; top: 50%; transform: translate(-50%, -50%); text-align: center; // display: flex; // justify-content: center; // align-items: center; // flex-wrap: wrap; } } } .caropper {display: flex; justify-content: space-between; padding-top: 10px; .icon-font { display: flex; cursor: pointer; .icon { color: #999999; margin-left: 20px; font-size: 14px; } } }.repeat-img {font-size: 14px; font-family: PingFangSC-Regular; font-weight: 400; color: rgba(255, 179, 85, 1); cursor: pointer; } .imgPrew {background: rgba(238, 238, 238, 1); text-align: center; margin-top: 40px; .prewImg { width: 100% !important; height: 100% !important; box-shadow: 15px 0px 55px 17px rgba(0, 0, 0, 0.05); overflow: hidden; } img {width: 100%; height: 100%; } h5 {font-size: 14px; font-family: PingFangSC-Regular; font-weight: 400; color: rgba(153, 153, 153, 1); line-height: 20px; } } } } </style>
转载于:https://www.cnblogs.com/sunny-shine/p/10677997.html
图片裁剪 cropper.js 上传组件封装 vue相关推荐
- vue 文件上传组件封装
增加图片缩略图以及Word.txt文档在线预览 文件上传组件完整代码 <template><div><el-uploadclass="upload-demo&q ...
- antd design Upload文件上传,删除,批量上传组件封装
1.单个文件上传组件,无文件时显示上传,有文件时显示文件,可删除,重新上传,样式适合图片上传,可根据文件格式更改样式,效果图如下. 页面调用代码 <FormItem{...formItemLay ...
- 图片裁剪和异步上传插件--一步到位(记录)
图片上传裁剪这功能随处可见,有的自己写,不过太耗费时间了,插件的话感觉好多,前段时间就想挑一款好的插件,以后就用那款,可是挑了几款插件用上去,效果很好,问题就出在合并了,单一的插件效果是很好的,没问题 ...
- 前端图片裁剪cropper.js
背景:我们在项目中常常都会有更换登陆人头像的需求,这个很简单直接上传一张图片展示就可以了,但是如果上传的图片需要剪裁成正方形的话就需要我们来做一些特殊的处理: 这里我们会用到一个图片剪裁插件:crop ...
- js截取图片 裁剪图片之cropper.js插件用法详解
js截取图片 裁剪图片之cropper.js插件用法详解 源码:https://github.com/fengyuanchen/cropper 引入+使用 <link href="/p ...
- vue-simple-uploader上传组件
一个由simple-uploader.js提供支持的 Vue.js 上传组件 vue-simple-uploader是基于 simple-uploader.js 封装的vue上传插件.它的优点包括且不 ...
- vue使用cropperjs实现移动端图片裁剪上传组件
本组件基于vuejs框架, 使用ES6基本语法, css预编译采用的scss, 图片裁剪模块基于cropperjs,拍照时的图片信息获取使用exif, 图片上传使用XMLHttpRequest 该组件 ...
- 如何上传图片到fileupload空间_如何用原生js写图片上传组件v2.0(还有新版本)?...
js图片上传组件: 基本要求: 1.上传的图片可预览,可删除,可被覆盖更新 2.要求图片格式为jpg和png,大小不能超过2M 新加需求: 1.模拟回显,可用本地存储(实际上的回显是通过后台传过来的u ...
- Vue菜鸟之路: 封装上传组件
为什么80%的码农都做不了架构师?>>> 前言 vue的菜鸟学习之路,从封装一个简单的上传组件开始,菜鸟摸索,大佬轻喷..(不服可以来写Java ....当我没说) 设计 1. ...
最新文章
- 视图、触发器、事务、存储过程、函数
- C++的IO流的函数
- 97. Leetcode 剑指 Offer 60. n个骰子的点数 (动态规划-背包问题)
- SAP 请求号单个传输方法
- python连接mongodb进行查询_Python中的MongoDB基本操作:连接、查询实例
- JAVA8 ARRAY、LIST操作 汇【5】)- JAVA8 LAMBDA LIST统计(求和、最大、最小、平均)
- spring属性注入
- 1000 驱动_布加迪首款SUV渲染图曝光!采用纯电驱动,马力或将突破1000匹!
- java过滤器应用实例_Servlet过滤器Filter的简单介绍(附示例)
- JavaScript中this关键字的使用比较
- (转)独家| ICO被定性为涉嫌非法集资 一夜暴富梦碎
- Aqua Data Studio v19.0 安装使用
- 数据通信原理_卫星通信系统原理什么 卫星通信系统原理介绍【图文】
- 我男朋友是产品经理......
- 2位8421bcd码相加实验
- Sql 存储过程传递参数
- 博通wifi 芯片配置工具wl 详解
- openwrt配置虚拟多wan
- 最新最酷Android手机游戏灵活的球球代码
- 【C++面向对象程序设计】CH3 怎样使用类和对象