,头像裁剪裁剪功能做了大概有五天,效率太低了,有时候遇到问题不知道该怎么下手,在此非常感谢同事的耐心指导,下面是基于cropper插件做的头像裁剪的功能,里面使用到了如何获取base64,以及图片压缩处理
cropperjs插件
cropper使用文档
插件的安装及使用方法文档里面都有详细的说明
安装:
npm install cropperjs
使用
在参考文档的基础上,想要实现的功能是:点击上传图片,上传后跳转到模态框,进行裁剪。这里会有一个图片大小的问题,裁剪后的图片在保存时会扩大2倍,所以要做一个压缩处理
上传图片
photo.vue
1.设置一个img
//点击上传照片
//必须给图片设置宽高
img{max-width: 100%;max-height: 100%;}
2.图片从状态管理中获取
computed: {...mapGetters({'getUrl': 'getUrl'}),imgUrl() {if (this.getUrl.url && this.getUrl.url.startsWith('http')) {return this.getUrl.url}//返回默认图片return defaultPhoto}}
如何获取图片的base64
3.图片上传方法
methods: {...mapActions(['setModelBaseInfo', 'setPhotoUploadComponent']),/*** 上传图片* @param event*/handlerChange(event) {let file = event.target.files[0]if (!file) {return}let type = file.type || ''if ((type !== "image/jpeg" && type !== "image/png")) {alert('上传失败’)//置空event.target.value = nullreturn}let that = this// 获取并记录图片的base64编码let reads = new FileReader()// 读出base64reads.readAsDataURL(file)reads.onloadend = function() {var dataURL = reads.result// 跳转到模态框进行裁剪that.UploadComponent(dataURL)event.target.value = null}}},
模态框处理
modal.vue
1.模态框template
//点击保存时 图片需要一定时间保存,所以加一个loading
保存保存中
2.引入cropper插件
import 'cropperjs/dist/cropper.css'
import Cropper from 'cropperjs'
3.设置cropper的opptions属性
//使用过程中多处会调用cropper,所以直接写在data里面 方便调用
data() {return {cropper: ''}},mounted() {this.init()},
methods: {
//写一个方法,便于调用init() {//图片存在的情况下执行裁剪操作if (this.$refs.img) {this.cropper = new Cropper(this.$refs.img, {//此处为options属性,可根据实际需求改变aspectRatio: 3 / 4,autoCropArea: 0.75,viewMode: 2,background: false,rounded: true})}}}
base64去前缀
fitler(base) {let str = 'base64,'return base.slice(base.indexOf(str) + str.length)}
获取base64大小
getBase64Size(base64) {let eqTagIndex = base64.indexOf("=")base64 = eqTagIndex != -1 ? base64.substring(0, eqTagIndex) : base64let strLen = base64.lengthreturn strLen - (strLen / 8) * 2}
压缩图片
scaleImg(base64, percent, cb) {let _img = new Image()_img.src = base64_img.onload = function() {let _canvas = document.createElement("canvas")_canvas.setAttribute("width", this.width)_canvas.setAttribute("height", this.height)_canvas.getContext("2d").drawImage(this, 0, 0, this.width, this.height)let data = _canvas.toDataURL("image/jpeg", percent)cb(data)}
保存图片
modal.vue
//点击保存按钮
handleClick() {const croppedCanvas = this.cropper.getCroppedCanvas()const MAX_SIZE = 10 * 1024 * 1024let base64 = croppedCanvas.toDataURL() // 获取到裁剪的地址let size = this.getBase64Size(base64)if (size {this.clickUpload(data)})}},clickUpload(data) {//此处可以做提示条 正在上传alert('上传中’)//Upload 请求服务this.Upload({name: 'a.jpg',pic: this.filter(data)}).then(res => {if (res.result === 'ok') {this.updateUrlStore(res.data || '')alert('uploadsuccess')} else {alert('uploadfail')}}).catch(() => {alert('uploadfail')})},/*** 同步到store*/updateUrlStore(url) {this.setModal({...this.modal,url})//同步模态框this.setCurrentComponent()},
遇到的问题
1.图片第一次上传裁剪后,二次上传同一图片时无反应
图片第一次上传请求接口没有问题,第二次点击没有正常请求接口
原因是第一次上传成功时,触发的onchange事件,onchange事件会在内容改变且失去焦点时触发,而第二次上传的图片还是上一次的图片的话,就不会触发这个onchange事件,从而导致图片上传失败.
解决方案:每次上传之后,都把值清空,比如e.target.value = null属性和自带的方法
总结
首先,在阅读插件文档的时候,要弄明白它的使用规则,如何调用.我在前期花了很多时间在文档上,不太清楚如何使用插件自带的方法。其次,在实际开发过程中,会遇到很多的bug,多数与调取数据有关,以及对vue语法的使用的不熟悉,写好了方法,不知道该在哪里去调用。所以要更多地去熟悉vue!
资源参考
压缩base64
cropperjs
模态框