1.在用户上传前在before-upload钩子获取files文件,然后中断上传操作
beforeAvatarUpload (files) {
this.filename = files.name
this.openCropper(files)
return false
}
然后在openCropper方法中用FileReader对读取文件并打开自己的cropper组件
openCropper (file) {
var _this = this
var reader = new FileReader()
reader.onload = e => {
let data
if (typeof e.target.result === 'object') {
// 把Array Buffer转化为blob 如果是base64不需要
data = window.URL.createObjectURL(new Blob([e.target.result]))
} else {
data = e.target.result
}
_this.option.img = data
_this.$refs.dialog.showDialog = true
}
// 转化为base64
// reader.readAsDataURL(file)
// 转化为blob
reader.readAsArrayBuffer(file)
},
这是我cropper的界面和配置,不展开细讲
<custom-dialog title="封面裁剪"
ref="dialog"
width="50%"
@confirm="handleConfirm"
:dialogConfig="{ showFooter: true, name: '确定', headCenter: true }">
<div class="cropper-w">
<div class="cropper"
:style="{ width: '320px', height: '180px' }">
<vueCropper ref="cropper"
v-if="crap"
:img="option.img"
:outputSize="option.size"
:outputType="option.outputType"
:info="option.info"
:full="option.full"
:canMove="option.canMove"
:canMoveBox="option.canMoveBox"
:original="option.original"
:autoCrop="option.autoCrop"
:autoCropWidth="option.autoCropWidth"
:autoCropHeight="option.autoCropHeight"
:fixedBox="option.fixedBox"></vueCropper>
</div>
<div class="tips">tips:滚动鼠标滚轮可进行缩放操作</div>
</div>
</custom-dialog>
option: {
img: '', // 裁剪图片的地址
info: false, // 裁剪框的大小信息
outputSize: 1, // 剪切后的图片质量(0.1-1)
full: true, // 输出原图比例截图 props名full
outputType: 'png', // 裁剪生成额图片的格式
canMove: true, // 能否拖动图片
original: false, // 上传图片是否显示原始宽高
canMoveBox: false, // 能否拖动截图框
autoCrop: true, // 是否默认生成截图框
autoCropWidth: 320,
autoCropHeight: 180,
fixedBox: true // 截图框固定大小
},
用户上传成功后点确定就会调用handleConfirm方法
handleConfirm () {
// 上传图片(点击上传按钮)
if (!this.option.img) {
return
}
// 输出
// if (this.outputType !== 'blob') {
this.$refs.cropper.getCropBlob((data) => {
if (data.size > 2097152) {
this.showMsg('图片大于2M,请进行裁剪或重新选择')
}
let blob = window.URL.createObjectURL(data)
this.downImg = blob
var base64;
var img = new Image()
img.src = blob
var _that = this
img.onload = function () {
var that = this
//生成比例
var w = that.width,
h = that.height,
scale = w / h
h = w / scale
//生成canvas
var canvas = document.createElement('canvas')
var ctx = canvas.getContext('2d')
canvas.width = w
canvas.height = h
ctx.drawImage(that, 0, 0, w, h)
// 生成base64
_that.cropperPic = canvas.toDataURL('image/jpeg', 0.8)
_that.$refs.dialog.showDialog = false
let files = _that.transformToFiles(_that.cropperPic, _that.filename)
_that.temporaryCloseCropper = true
// 最后一步是 手动调用element组件的上传方法
// 举个例子
_that.$refs.upload.$children[0].handleChange({ target: { files: [files] } })
}
})
},
transformToFiles方法是我在网上找的一个将base64转成files的方法
transformToFiles (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 })
}
然后最后,我们拿到新的file需要重新调用el-upload的上传方法
_that.$refs.upload.$children[0].handleChange({ target: { files: [files] } })
这样就可以继续上传了!