Vue 使用 vue-cropper上传头像的剪切和预览,缩放、
上传头像,使用了有栈vant的 uploader打开相册,也使用了 vueCropper截取图片等!
效果图:
代码如下:
<template>
<div>
<div class="info-item" style="flex:1;margin-left:0;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/*" @change="uploadImg($event, 1)">-->
<span class="btn-orange">
<van-uploader :multiple="false"
:after-read="afterRead"
:preview-image="false"
:max-count="1"
:show-upload="true"
accept="image/*">
<van-button icon="plus" type="primary">上传文件</van-button>
</van-uploader>
</span>
<input type="button" class="oper" style="margin:3px 5px;" value="+" title="放大" @click="changeScale(1)">
<input type="button" class="oper" style="margin:3px 5px;" value="-" title="缩小" @click="changeScale(-1)">
<input type="button" class="oper" style="margin:3px 5px;" value="↺" title="左旋转" @click="rotateLeft">
<input type="button" class="oper" style="margin:3px 5px;" value="↻" title="右旋转" @click="rotateRight">
<input type="button" class="oper" style="margin:3px 5px;" value="↓" title="下载" @click="down('blob')">
<input type="button" class="btn btn-blue" value="上传头像" @click="finish('blob')">
<div class="line" style="margin-top: 20px;">
<div class="cropper-content">
<div class="cropper">
<vueCropper
ref="cropper"
:img="option.img"
:outputSize="option.size"
:outputType="option.outputType"
:info="false"
:centerBox="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"
class="cropperImg"
></vueCropper>
</div>
</div>
</div>
</div>
<!--<div style="margin-top: 30px">
<div class="show-preview" :style="{'width': '150px', 'height':'150px', }">
<div :style="previews.div" class="preview">
<img :src="previews.url" :style="previews.img">
</div>
</div>
</div>-->
</div>
</template>
<script>
import { VueCropper } from "vue-cropper";
export default {
data() {
return {
tempArr:[],
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:'',
maxSize:10 * 1024 * 1024,//定义照片最大10M
type:''
}
},
components: {
vueCropper: VueCropper
},
methods: {
afterRead(file){
if(this.tempArr.length===0){
this.type="";
}
this.$toast.loading()
//单个文件
let fileType = null;
if(file.file.type.indexOf( 'image') !== -1) {
fileType = "image";
}
if(!fileType) {
this.$toast.fail("请上传图片");
return
}
this.option.img=file.content;
this.fileName=file.file.name;
},
//放大/缩小
changeScale(num) {
num = num || 1;
this.$refs.cropper.changeScale(num);
},
//坐旋转
rotateLeft() {
this.$refs.cropper.rotateLeft();
},
//右旋转
rotateRight() {
this.$refs.cropper.rotateRight();
},
//上传图片(点击上传按钮)
finish() {
if(!this.fileName){
this.$toast({
message:'暂无选择文件'
})
return
}
let formData = new FormData();
// 输出
this.$refs.cropper.getCropBlob(data => {
let img = window.URL.createObjectURL(data);
console.log(img);
//下面这两个都可以
//formData.append("file", data, img);
//formData.append("file", data);
formData.append("file", data, this.fileName);
this.$api.image(formData).then(res => {
let imgUrl=this.$resData(res);
if(imgUrl){
this.$api.modHeadPortrait({
headPortrait:imgUrl
}).then(res=>{
if(res.status===200){
// this.getUserInfo();
this.$toast({
message:"修改头像成功"
})
}else{
this.$toast({
message:"修改头像失败"
})
}
})
}else{
this.$toast({
message:"网络请求失败"
})
}
});
});
},
// 实时预览函数
realTime(data) {
this.previews = data
},
//下载图片
down(type) {
let a=this.$util.isWxBrowser();
alert(a)
let 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) {
let _this = this;
//上传图片
let 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
}
//限制大小
if (file.size > _this.maxSize) {
alert("图片不能超过10M");
return;
}
let 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('msg'+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: 10px;
}
}
}
.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: -webkit-flex;
justify-content: flex-end;
-webkit-justify-content: flex-end;
.cropper{
width: 260px;
height: 260px;
margin: 0 auto;
.cropper-crop-box{
border-radius: 50%;
width: 150px !important;
height: 150px !important;
overflow: hidden;
}
}
}
.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;
width: 150px !important;
height: 150px !important;
}
}
.show-preview .preview {margin-left: 0;}
.show-preview{
margin: 0 auto;
}
</style>
注意:在PC端下载图片是可以的,但是在微信浏览器上下载是不起作用的!