最近自己在研究vue,然后做了一個小型的后台管理系統用來練手,開發過程中,想到了剪切圖片上傳用戶頭像的需求。上網百度了一番,發現好多用的都是vue-cropper。我也就用了,個人感覺還是挺好用的。現在在這里用一個簡單的小demo演示一下vue-cropper的使用方法。
其中上傳用戶頭像的接口是java寫的,感興趣的話可以參考我的2017年12月2號的博客:前后端分離跨服務器文件上傳-Java SpringMVC版
1、安裝vue-cropper
使用npm本地安裝vue-cropper
npm install vue-cropper --save-dev
2、新建一個test.vue文件
該文件只做用來演示剪切上傳圖片的功能,下面直接貼出代碼
test.vue:
<template>
<div style="display:flex;">
<div class="info-item" style="flex:1;">
<div style="width:120px;height:120px;border-radius:50%;overflow:hidden;margin-left:123px;border:1px solid #ddd">
<img style="width:120px;height:120px;" :src="headImg" alt="頭像">
</div>
</div>
<div class="info-item" style="flex:1;margin-left:-160px;margin-top:30px;">
<label class="btn btn-orange" for="uploads" style="display:inline-block;width: 70px;padding: 0;text-align: center;line-height: 28px;">選擇圖片</label>
<input type="file" id="uploads" :value="imgFile" style="position:absolute; clip:rect(0 0 0 0);" accept="image/png, image/jpeg, image/gif, image/jpg" @change="uploadImg($event, 1)">
<input type="button" class="oper" style="height:20px;width:23px;font-size:20px;margin:3px 5px;" value="+" title="放大" @click="changeScale(1)">
<input type="button" class="oper" style="height:20px;width:23px;font-size:20px;margin:3px 5px;" value="-" title="縮小" @click="changeScale(-1)">
<input type="button" class="oper" style="height:20px;width:23px;font-size:20px;margin:3px 5px;" value="↺" title="左旋轉" @click="rotateLeft">
<input type="button" class="oper" style="height:20px;width:23px;font-size:20px;margin:3px 5px;" value="↻" title="右旋轉" @click="rotateRight">
<input type="button" class="oper" style="height:20px;width:23px;font-size:20px;margin:3px 5px;" value="↓" title="下載" @click="down('blob')">
<input type="button" class="btn btn-blue" value="上傳頭像" @click="finish('blob')">
<div class="line" style="margin-left: -280px;margin-top: 85px;">
<div class="cropper-content" style="margin-top:-60px;margin-left:260px;">
<div class="cropper">
<vueCropper
ref="cropper"
:img="option.img"
:outputSize="option.size"
:outputType="option.outputType"
:info="true"
:full="option.full"
:canMove="option.canMove"
:canMoveBox="option.canMoveBox"
:original="option.original"
:autoCrop="option.autoCrop"
:autoCropWidth="option.autoCropWidth"
:autoCropHeight="option.autoCropHeight"
:fixedBox="option.fixedBox"
@realTime="realTime"
@imgLoad="imgLoad"
></vueCropper>
</div>
<div style="margin-left:20px;">
<div class="show-preview" :style="{'width': '150px', 'height':'155px', 'overflow': 'hidden', 'margin': '5px'}">
<div :style="previews.div" class="preview">
<img :src="previews.url" :style="previews.img">
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import VueCropper from 'vue-cropper'
import Api from '@/js/api.js' //接口url配置文件
export default {
data() {
return {
headImg:'',
//剪切圖片上傳
crap: false,
previews: {},
option: {
img: '',
outputSize:1, //剪切后的圖片質量(0.1-1)
full: false,//輸出原圖比例截圖 props名full
outputType: 'png',
canMove: true,
original: false,
canMoveBox: true,
autoCrop: true,
autoCropWidth: 150,
autoCropHeight: 150,
fixedBox: true
},
fileName:'', //本機文件地址
downImg: '#',
imgFile:'',
uploadImgRelaPath:'', //上傳后的圖片的地址(不帶服務器域名)
}
},
components: {
VueCropper
},
methods: {
//放大/縮小
changeScale(num) {
console.log('changeScale')
num = num || 1;
this.$refs.cropper.changeScale(num);
},
//坐旋轉
rotateLeft() {
console.log('rotateLeft')
this.$refs.cropper.rotateLeft();
},
//右旋轉
rotateRight() {
console.log('rotateRight')
this.$refs.cropper.rotateRight();
},
//上傳圖片(點擊上傳按鈕)
finish(type) {
console.log('finish')
let _this = this;
let formData = new FormData();
// 輸出
if (type === 'blob') {
this.$refs.cropper.getCropBlob((data) => {
let img = window.URL.createObjectURL(data)
this.model = true;
this.modelSrc = img;
formData.append("file", data, this.fileName);
this.$http.post(Api.uploadSysHeadImg.url, formData, {contentType: false, processData: false, headers:{'Content-Type': 'application/x-www-form-urlencoded'}})
.then((response)=>{
var res = response.data;
if(res.success == 1){
$('#btn1').val('');
_this.imgFile = '';
_this.headImg = res.realPathList[0]; //完整路徑
_this.uploadImgRelaPath = res.relaPathList[0]; //非完整路徑
_this.$message({ //element-ui的消息Message消息提示組件
type: 'success',
message: '上傳成功'
});
}
})
})
} else {
this.$refs.cropper.getCropData((data) => {
this.model = true;
this.modelSrc = data;
})
}
},
// 實時預覽函數
realTime(data) {
console.log('realTime')
this.previews = data
},
//下載圖片
down(type) {
console.log('down')
var aLink = document.createElement('a')
aLink.download = 'author-img'
if (type === 'blob') {
this.$refs.cropper.getCropBlob((data) => {
this.downImg = window.URL.createObjectURL(data)
aLink.href = window.URL.createObjectURL(data)
aLink.click()
})
} else {
this.$refs.cropper.getCropData((data) => {
this.downImg = data;
aLink.href = data;
aLink.click()
})
}
},
//選擇本地圖片
uploadImg(e, num) {
console.log('uploadImg');
var _this = this;
//上傳圖片
var file = e.target.files[0]
_this.fileName = file.name;
if (!/\.(gif|jpg|jpeg|png|bmp|GIF|JPG|PNG)$/.test(e.target.value)) {
alert('圖片類型必須是.gif,jpeg,jpg,png,bmp中的一種')
return false
}
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
}
if (num === 1) {
_this.option.img = data
} else if (num === 2) {
_this.example2.img = data
}
}
// 轉化為base64
// reader.readAsDataURL(file)
// 轉化為blob
reader.readAsArrayBuffer(file);
},
imgLoad (msg) {
console.log('imgLoad')
console.log(msg)
}
},
}
</script>
<style lang="less">
.info {
width: 720px;
margin: 0 auto;
.oper-dv {
height:20px;
text-align:right;
margin-right:100px;
a {
font-weight: 500;
&:last-child {
margin-left: 30px;
}
}
}
.info-item {
margin-top: 15px;
label {
display: inline-block;
width: 100px;
text-align: right;
}
.sel-img-dv {
position: relative;
.sel-file {
position: absolute;
width: 90px;
height: 30px;
opacity: 0;
cursor: pointer;
z-index: 2;
}
.sel-btn {
position: absolute;
cursor: pointer;
z-index: 1;
}
}
}
}
.cropper-content{
display: flex;
display: -webkit-flex;
justify-content: flex-end;
-webkit-justify-content: flex-end;
.cropper{
width: 260px;
height: 260px;
}
.show-preview{
flex: 1;
-webkit-flex: 1;
display: flex;
display: -webkit-flex;
justify-content: center;
-webkit-justify-content: center;
.preview{
overflow: hidden;
border-radius: 50%;
border:1px solid #cccccc;
background: #cccccc;
margin-left: 40px;
}
}
}
.cropper-content .show-preview .preview {margin-left: 0;}
</style>
其中,js/api.js文件是配置的接口地址
3、效果
1、打開頁面效果

2、點擊選擇圖片按鈕,選擇完本地圖片后的效果

選擇完圖片后,就可以對圖片進行放大,縮小以及旋轉等,並且可以移動選中框,選擇上傳圖片的任意部分
3、點擊上傳頭像按鈕,即可調用上傳頭像的接口,把頭像上傳到文件服務器

此時,圖片便已上傳成功了,查看圖片服務器指定的目錄,即可查看到圖片已經在服務器上了

需要購買阿里雲產品和服務的,點擊此鏈接領取優惠券紅包,優惠購買哦,領取后一個月內有效: https://promotion.aliyun.com/ntms/yunparter/invite.html?userCode=fp9ccf07
