在vue中使用vue-cropper圖片裁剪並上傳圖片(配合ant-design-vue的upload元件)
阿新 • • 發佈:2020-08-18
在vue中使用vue-cropper圖片裁剪並上傳圖片
思路:封裝一個對話方塊(Modal),裡面包含一個vue-cropper,用於ant-upload上傳檔案時呼叫彈出此對話方塊讓使用者編輯此圖片.裁剪完emit一個事件,然後上傳這個編輯後的圖片(file)
先是對vue-cropper進行再封裝
該元件就對外''暴露 "2個操作 1. 傳入影象資料並開啟對話方塊 2. 影象處理完後返回影象資料 這使用起來方便
碼來:src\components\common\cropper-modal.vue
<template> <a-modal :visible="visible" title="請裁剪圖片" :maskClosable="false" :confirmLoading="confirmLoading" @cancel="handleCancel" @ok="handleOk" > <div class="cropper-wrapper"> <vue-cropper ref="cropper" :img="img" :info="true" :original="true" :autoCrop="options.autoCrop" :autoCropWidth="options.autoCropWidth" :autoCropHeight="options.autoCropHeight" :fixedBox="options.fixedBox" ></vue-cropper> </div> </a-modal> </template> <script> import { VueCropper } from 'vue-cropper' export default { components: { VueCropper, }, data() { return { // ant-modal相關配置 visible: false, confirmLoading: false, // vue-cropper相關配置 詳細的可以去github上看文件 img: null, //要裁剪的影象資源 可選項: url地址 || base64 || blob options: { autoCrop: true, //是否預設生成截圖框 autoCropWidth: 200, //預設生成截圖框寬度 autoCropHeight: 200, //預設生成截圖框高度 fixedBox: true, //固定截圖框大小 不允許改變 }, } }, methods: { // 呼叫此方法需傳入一個 [url地址 || base64 || blob] // 父元件呼叫: this.$refs['cropperModal'].edit(引數) edit(image) { this.img = image this.visible = true }, // 監聽對話方塊的OK/Cancel按鈕的點選事件 handleOk() { const that = this that.confirmLoading = true // 獲取截圖的base64 資料 // getCropBlob獲取二進位制資料 this.$refs.cropper.getCropData((data) => { //將裁剪侯後的圖片物件射給**父元件**,然後關閉對話方塊 that.$emit('ok', data) that.handleCancel() }) }, handleCancel(e) { this.visible = false }, }, } </script> <style lang="scss" scoped> .cropper-wrapper { width: 100%; height: 400px; } </style>
父元件是用了ant-design-vue的upload元件
關鍵程式碼如下:顯示為一個按鈕,點選更換頭像後彈出檔案選擇框,再選擇檔案後先是呼叫beforeUpload
判斷檔案型別,滿足條件然後呼叫
handleUploadChange
函式
@ok="handleOK"
就是在圖片裁剪後 emit的ok事件
<a-upload :before-upload="beforeUpload" :show-upload-list="false" :custom-request="function(){}" @change="handleUploadChange" > <a-button type="primary">更換頭像</a-button> </a-upload> <cropper-modal @ok="handleOK" ref="cropperModal" />
// 在父元件的methods中 // 選擇檔案後且beforeUpload返回為true後會呼叫這個方法 handleUploadChange(info) { // 這個回撥函式的引數是個File物件,所以要用FileReader將物件轉換成 data-uri (base64) 物件,才能給vue-cropper var reader = new FileReader() const _this = this // 當檔案處理完成的回撥函式 reader.onload = function (e) { // e.target.result 該屬性表示目標物件的DataURL // 然後呼叫cropperModal的edit方法使得對話方塊可見 _this.$refs['cropperModal'].edit(e.target.result) } // 記錄原始的檔名字,用於DataURL(base64)轉成file物件,不轉就可以不用 this.tmpImgName = info.file.name // 檔案處理 file=>base64 reader.readAsDataURL(info.file.originFileObj) }, // 對檔案格式校驗(ant-upload選擇檔案框是所有型別的) beforeUpload(file) { var fileType = file.type console.log(file.type) if (fileType.indexOf('image') < 0) { this.$message.warning('請上傳圖片') return false } }, // 然後這裡可以呼叫api請求上傳圖片 handleOK(data) { console.log(data) let file = this.dataURLtoFile(data, this.tmpImgName) console.log(file) // ....省略api請求 2種格式的物件都拿到了 怎麼請求不用說了吧 }, // 將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 }) },
附帶一個axios上傳multipart格式的檔案方法
// 上傳頭像 File型別
uploadAvatar(file) {
let param = new FormData() // 建立form物件
param.append('file', file) // 通過append向form物件新增資料
// param.append('chunk', '0') // 新增form表單中其他資料
let config = {
headers: { 'Content-Type': 'multipart/form-data' }
}
return axios.post('/upload/avatar', param, config)
},
參考連結
文件教程:http://github.xyxiao.cn/vue-cropper/example/
他人教程:https://www.jianshu.com/p/4024cf503380
結合antv:https://blog.csdn.net/qq_36111804/article/details/94599536
HTML5 file物件和blob物件的互相轉換 https://www.jianshu.com/p/5b44c41adfe2