vue-cropper插件實(shí)現(xiàn)圖片截取上傳組件封裝
基于vue-cropper插件實(shí)現(xiàn)圖片截取上傳組件封裝的具體代碼,供大家參考,具體內(nèi)容如下
需求場(chǎng)景:
后臺(tái)開(kāi)發(fā)需要上傳圖片并進(jìn)行相應(yīng)比例尺寸圖片的截取,本組件開(kāi)發(fā)采用Ant Design Vue組件庫(kù)搭配vue-cropper插件進(jìn)行封裝
實(shí)現(xiàn)如下


html
<template>
<div>
<a-upload
name="avatar"
list-type="picture-card"
class="avatar-uploader"
:show-upload-list="false"
:custom-request="customRequest"
:before-upload="beforeUpload"
:style="`width: ${width}; height: ${height};`"
>
<img
v-if="imageUrl && !loading"
:src="imageUrl"
alt="avatar"
:style="`width: ${width}; height: ${height};`"
/>
<div v-else>
<a-icon :type="loading ? 'loading' : 'plus'" />
<div class="ant-upload-text">上傳圖片</div>
</div>
</a-upload>
<a-modal
v-model="imageCut.isShowModal"
title="圖片截取"
width="400px"
@ok="finish"
@cancel="imageCut.close"
>
<div class="cropper-content" v-if="imageCut.isShowModal">
<div class="cropper" style="text-align:center">
<vueCropper
ref="cropper"
:img="imageCut.imgFile"
:outputSize="outputSize"
:outputType="outputType"
:info="info"
:full="full"
:canMove="canMove"
:canMoveBox="canMoveBox"
:original="original"
:autoCrop="autoCrop"
:fixed="fixed"
:fixedNumber="fixedNumber"
:centerBox="centerBox"
:infoTrue="infoTrue"
:fixedBox="fixedBox"
></vueCropper>
</div>
</div>
</a-modal>
</div>
</template>
js
<script>
import { uploadImage } from '@/api/common'
import { VueCropper } from "vue-cropper";
export default {
name: 'ImageUpload',
components: { VueCropper },
data() {
return {
loading: false,
imageCut: {
isShowModal: false,
imgFile: '',
init: imgFile => {
this.imageCut.imgFile = imgFile
this.imageCut.isShowModal = true
},
close: () => {
this.imageCut.imgFile = ''
this.imageCut.isShowModal = false
}
}
}
},
props: {
imageUrl: String,
width: {
type: String,
default: '100px'
},
height: {
type: String,
default: '100px'
},
canCut: {
type: Boolean,
default: false
},
info: {
type: Boolean,
default: false
}, // 裁剪框的大小信息
outputSize: {
type: Number,
default: 0.8
}, // 裁剪生成圖片的質(zhì)量
outputType: {
type: String,
default: 'jpeg'
}, // 裁剪生成圖片的格式
canScale: {
type: Boolean,
default: true
}, // 圖片是否允許滾輪縮放
autoCrop: {
type: Boolean,
default: true
}, // 是否默認(rèn)生成截圖框
// autoCropWidth: 300, // 默認(rèn)生成截圖框?qū)挾?
// autoCropHeight: 200, // 默認(rèn)生成截圖框高度
fixedBox: {
type: Boolean,
default: false
}, // 固定截圖框大小 不允許改變
fixed: {
type: Boolean,
default: true
}, // 是否開(kāi)啟截圖框?qū)捀吖潭ū壤?
fixedNumber: {
type: Array,
default: () => [1, 1]
}, // 截圖框的寬高比例
full: {
type: Boolean,
default: true
}, // 是否輸出原圖比例的截圖
canMove: {
type: Boolean,
default: false
},
canMoveBox: {
type: Boolean,
default: true
}, // 截圖框能否拖動(dòng)
original: {
type: Boolean,
default: false
}, // 上傳圖片按照原始比例渲染
centerBox: {
type: Boolean,
default: true
}, // 截圖框是否被限制在圖片里面
infoTrue: {
type: Boolean,
default: true
} // true 為展示真實(shí)輸出圖片寬高 false 展示看到的截圖框?qū)捀?
},
methods: {
beforeUpload(file) {
const isJpgOrPng = file.type === 'image/jpeg' || file.type === 'image/png'
if (!isJpgOrPng) {
this.$message.error('請(qǐng)上傳JPG或PNG文件!')
}
const isLt2M = file.size / 1024 / 1024 < 2
if (!isLt2M) {
this.$message.error('請(qǐng)上傳2MB以下文件!')
}
return isJpgOrPng && isLt2M
},
customRequest(file) {
if (this.canCut) {
this.readFile(file.file)
} else {
this.loading = true
const formData = new FormData()
formData.append('fileIdcard', file.file)
uploadImage(formData).then(res => {
this.loading = false
this.$emit('uploadSuccess', res.ossUrl)
})
}
},
readFile(file) {
var reader = new FileReader()
reader.readAsDataURL(file)
reader.onload = () => {
this.imageCut.init(reader.result)
}
},
finish() {
this.$refs.cropper.getCropBlob(data => {
this.loading = true
// 上傳阿里云服務(wù)器
const formData = new FormData()
formData.append('fileIdcard', data)
uploadImage(formData).then(res => {
this.imageCut.close()
this.loading = false
this.$emit('uploadSuccess', res.ossUrl)
})
})
}
}
}
</script>
css
<style lang="less">
.avatar-uploader > .ant-upload {
width: 100%;
height: 100%;
}
.ant-upload-select-picture-card i {
font-size: 32px;
color: #999;
}
.ant-upload-select-picture-card .ant-upload-text {
margin-top: 8px;
color: #666;
}
.cropper-content {
.cropper {
width: auto;
height: 400px;
}
}
</style>
組件使用及說(shuō)明
<image-upload
:imageUrl="form.diagramUrl"
@uploadSuccess="uploadSuccess"
width="160px"
height="90px"
:can-edit="canCut"
:fixed-number="[16,9]"
/>
組件調(diào)用時(shí)需傳入canEdit屬性,指定組件是否啟動(dòng)圖片選取后的裁剪功能,默認(rèn)值為不啟用裁剪;需裁剪時(shí)可傳入fixedNumber屬性,定義裁剪框的寬高比
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Vue將el-table導(dǎo)出為excel文件的實(shí)現(xiàn)方法
在 Vue + Element UI 中,el-table 數(shù)據(jù)導(dǎo)出 Excel 文件,可以使用 xlsx(SheetJS)庫(kù)進(jìn)行處理,以下是詳細(xì)的實(shí)現(xiàn)方法,包括安裝依賴、代碼示例和優(yōu)化建議,需要的朋友可以參考下2025-02-02
vue性能優(yōu)化之cdn引入vue-Router的問(wèn)題
這篇文章主要介紹了vue性能優(yōu)化之cdn引入vue-Router的問(wèn)題及解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-08-08
VUE中setTimeout和setInterval自動(dòng)銷毀案例
這篇文章主要介紹了VUE中setTimeout和setInterval自動(dòng)銷毀案例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-09-09
vue不通過(guò)路由直接獲取url中參數(shù)的方法示例
通過(guò)url傳遞參數(shù)是我們?cè)陂_(kāi)發(fā)中經(jīng)常用到的一種傳參方法,但通過(guò)url傳遞后改如果獲取呢?下面這篇文章主要給大家介紹了關(guān)于vue如何不通過(guò)路由直接獲取url中參數(shù)的相關(guān)資料,需要的朋友可以參考借鑒,下面來(lái)一起看看吧。2017-08-08
vue3 響應(yīng)式對(duì)象如何實(shí)現(xiàn)方法的不同點(diǎn)
這篇文章主要介紹了vue3 響應(yīng)式對(duì)象如何實(shí)現(xiàn)方法的不同點(diǎn),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-05-05
el-table 動(dòng)態(tài)給每行增加class屬性的示例代碼
這篇文章主要介紹了el-table 動(dòng)態(tài)給每行增加class屬性的示例代碼,代碼簡(jiǎn)單易懂,對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧2025-03-03
Vue解決element-ui消息提示$message重疊問(wèn)題
這篇文章主要為大家介紹了Vue解決element-ui消息提示$message重疊問(wèn)題,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-08-08

