利用vue-cropper做的关于图片裁剪、压缩、上传、预览等做的一个公共组件
2018-09-28 22:13
1191 查看
公共组件:
<template> <div> <div class="upload-box"> <div class="image-box" v-if="imageUrl" :style="{'background-image': 'url('+ imageUrl +')', 'height': imageHeight}"></div> <div class="upload"> <h6 class="upload-des">支持 jpg、png 格式大小 5M 以内的图片</h6> <input type="file" @change="getFile" ref="file" id="file"> <label for="file">点击上传</label> </div> </div> <!-- vueCropper 剪裁图片实现--> <div class="vue-cropper-box" v-if="isShowCropper"> <div class="vue-cropper-content"> <vueCropper ref="cropper" :img="option.img" :outputSize="option.outputSize" :outputType="option.outputType" :info="option.info" :canScale="option.canScale" :autoCrop="option.autoCrop" :autoCropWidth="option.autoCropWidth" :autoCropHeight="option.autoCropHeight" :fixed="option.fixed" :fixedNumber="option.fixedNumber"> </vueCropper> </div> </div> <el-button v-if="isShowCropper" type="danger" @click="onCubeImg">确定裁剪图片</el-button> </div> </template> <script> import VueCropper from "vue-cropper" export default { name: 'Avatar', data () { return { //裁剪组件的基础配置option option: { img: '', //裁剪图片的地址 info: true, //裁剪框的大小信息 outputSize: 1, // 裁剪生成图片的质量 outputType: 'png', //裁剪生成图片的格式 canScale: false, // 图片是否允许滚轮缩放 autoCrop: true, // 是否默认生成截图框 autoCropWidth: 195, // 默认生成截图框宽度 autoCropHeight: 10, // 默认生成截图框高度 fixed: false, //是否开启截图框宽高固定比例 fixedNumber: [1, 1] //截图框的宽高比例 }, isShowCropper: false //是否显示截图框 } }, props: { // 特殊配置 cropperOption: { type: Object, default: () => { return null } }, // 默认图片 imageUrl: { type: String, default: '' }, // 图片展示高度 imageHeight: { type: String, default: '100px' } }, components: { VueCropper }, methods: { getFile (e) { let _this = this var files = e.target.files[0] if (!e || !window.FileReader) return // 看支持不支持FileReader let reader = new FileReader() reader.readAsDataURL(files) reader.onloadend = function () { _this.isShowCropper = true _this.option.img = this.result _this.$refs.file.value = '' } }, // 确定裁剪图片 onCubeImg () { this.$refs.cropper.getCropData((data) => { this.isShowCropper = false //console.log("压缩前的图片大小:" + data.length) let img = new Image(), _this = this img.src = data img.onload = function() { //let _data = _this.compress(img) let blob = _this.dataURItoBlob(data) let formData = new FormData() formData.append("icon", blob) //console.log("将blob对象转成formData对象:" + formData.get("icon")) _this.$emit('cropped', data, formData) } }) }, // 压缩图片 compress(img) { let canvas = document.createElement("canvas"), ctx = canvas.getContext("2d"), initSize = img.src.length, width = img.width, height = img.height; canvas.width = width canvas.height = height // 铺底色 ctx.fillStyle = "#fff" ctx.fillRect(0, 0, canvas.width, canvas.height) ctx.drawImage(img, 0, 0, width, height) //进行压缩 let ndata = canvas.toDataURL("image/jpeg", 0.8) //console.log("压缩后的图片大小:" + ndata.length) return ndata }, // base64转成bolb对象 dataURItoBlob(base64Data) { let byteString if (base64Data.split(",")[0].indexOf("base64") >= 0) byteString = atob(base64Data.split(",")[1]) else byteString = unescape(base64Data.split(",")[1]) let mimeString = base64Data .split(",")[0] .split(":")[1] .split(";")[0]; let ia = new Uint8Array(byteString.length); for (let i = 0; i < byteString.length; i++) { ia[i] = byteString.charCodeAt(i); } return new Blob([ia], { type: mimeString }) }, // 初始化配置文件 initOptions () { this.isShowCropper = false if (this.cropperOption) { for (let key in this.option) { this.option[key] = this.cropperOption[key] || this.option[key] } } } }, created () { this.initOptions() } } </script> <style scoped lang="stylus" rel="stylesheet"> .upload-box { & > div { display inline-block vertical-align middle } & .upload-des { margin 0 font-weight 400 color #909399 } } .image-box { width 100px height 100px margin-right 20px background-size 100px auto background-position left center background-repeat no-repeat } .upload { & label { width: 80px; height: 24px; font-size: 12px; line-height: 24px; display: inline-block; border-radius: 4px; text-align: center; border: 1px solid #ddd; cursor pointer } } input[type='file'] { display: none; } .vue-cropper-box { width: 60%; height: 200px; margin: 15px 0px; .vue-cropper-content { height 200px } } </style>
调用
<el-form-item label="头像" prop="icon" :rules="rules.required"> <Avatar v-on:cropped="doCrop" :cropperOption="cropperOption" :imageUrl="guestInfo.icon"></Avatar> </el-form-item>
注意下面这个二进制文件接收和上传的问题
resetForm(){ this.$nextTick(() => { this.$refs.guest.clearValidate() this.guestUpInfo = new FormData() }) },
//完成裁剪 doCrop(icon, file){ this.guestInfo.icon = icon this.guestUpInfo = file }
//新增、编辑提交 submitGuest(){ validCallback(this, 'guest', () => { this.guestUpInfo.append('name',this.guestInfo.name) this.guestUpInfo.append('position',this.guestInfo.position) this.guestUpInfo.append('description',this.guestInfo.description) if(this.guestInfo.seq){ this.guestUpInfo.append('seq',this.guestInfo.seq) } if(this.editGuest){ this.guestUpInfo.append('id',this.guestInfo.id) } publicSubmitApi('saveSpeaker', this.guestUpInfo, true).then(res => { if (res.status === 200) { this.guestShow = false this.fetchData() this.$message({ message: this.editGuest ? '编辑成功' : '新增成功', type: 'success' }) } }) }) },
相关文章推荐
- 一个支持图片上传前预览,裁剪的vue组件
- vue.js 实现图片本地预览 裁剪 压缩 上传功能
- 基于SpringBoot的图片上传组件,实现图片裁剪、Thumbnailator压缩的功能
- 从0开始做一个的Vue图片/ 文件选择(上传)组件[基础向]
- vue之使用Cropper进行图片剪裁上传压缩
- vue项目中编写一个图片预览的公用组件
- [置顶] 利用jquery和原生Js封装一个上传图片的组件
- 从0开始做一个的Vue图片/ 文件选择(上传)组件[基础向]
- 基于jQuery和cropper点击头像上传并预览裁剪图片
- Vue上传图片预览组件
- Vue.js 2.0 移动端拍照压缩图片预览及上传实例
- cropper js基于vue的图片裁剪上传功能的实现代码
- 基于cropper.js封装vue在线图片裁剪组件
- 关于图片上传和利用canvas进行压缩
- Vue.js 2.0 移动端拍照压缩图片上传预览功能
- Vue上传图片预览以及删除的vue组件
- Vue.js 2.0 移动端拍照压缩图片预览及上传 的全部源代码 lrz自己安装 npm i lrz --save -g 自己引入vux的 confirmplugin
- Vue上传图片预览以及删除的vue组件
- 利用开源组件commons-fileupload上传图片文件(1)