业务需求——头像图片裁剪后上传
具体代码如下:
<el-form-item label="宣传图片">
<el-avatar :key="avatarPreview" :size="150" shape="square" :src="avatarPreview" @click.native="openDialog"/>
<my-cropper ref="myCropper" @saveImgUrl="saveImgUrl"/>
</el-form-item>
<script>
import MyCropper from '@/extra/MyCropper';
import {baseURL} from "@/config/net.config";
import {getToken} from "@/utils/token";
export default {
components: {
MyCropper
},
data() {
return {
avatarPreview: '',
url: {
downloadFileURL: `${baseURL}/base/admin/testOrgan/download?X-Access- Token=${getToken()}&id=`,
}
}
},
methods: {
showEdit(row) {
let {imgPath} = row;
if (imgPath != null && String(imgPath).trim().length > 0) {
//请求后台获取图片流文件
this.avatarPreview = `${this.url.downloadFileURL}${row.id}`;
}
},
//裁剪完成后回调方法
saveImgUrl(data) {
this.avatarPreview = data;
this.form.avatar = data;
},
//弹出裁剪对话框
openDialog() {
this.$refs['myCropper'].initShow(this.avatarPreview);
},
}
}
</script>
net.config.js文件(后台获取图片流)
/**
* @description 导出网络配置
**/
module.exports = {
// 默认的接口地址,开发环境和生产环境都会走/vab-mock-server
// 正式项目可以选择自己配置成需要的接口地址,如"https://api.xxx.com"
// 问号后边代表开发环境,冒号后边代表生产环境
baseURL:
process.env.NODE_ENV === 'development'
? '/manage-boot'
: '这里正式地址域名',
// 配后端数据的接收方式application/json;charset=UTF-8 或 application/x-www-form-urlencoded;charset=UTF-8
contentType: 'application/json;charset=UTF-8',
// 最长请求时间
requestTimeout: 90000,
// 操作正常code,支持String、Array、int多种类型
successCode: [200, 0, '200', '0',true],
// 数据状态的字段名称
statusName: 'code',
// 状态信息的字段名称
messageName: 'message',
}
我使用的是"vue-cropper": "^0.4.8"版本的裁剪组件,需要在main.js全局注册一下
npm install vue-cropper@0.4.8 --save
import VueCropper from 'vue-cropper';
Vue.use(VueCropper)
MyCropper组件
<template>
<el-dialog
:close-on-click-modal="false"
title="宣传图片"
:visible.sync="dialogVisible"
:modal="false"
:destroy-on-close="true"
width="800px"
>
<el-row>
<el-col :xs="24" :md="12" :style="{height: '350px'}">
<vue-cropper
ref="cropper"
:img="options.img"
:info="true"
:autoCrop="options.autoCrop"
:fixedBox="options.fixedBox"
:canMoveBox="options.canMoveBox"
:autoCropWidth="options.autoCropWidth"
:autoCropHeight="options.autoCropHeight"
:centerBox="options.centerBox"
:fixed="options.fixed"
:fixedNumber="options.fixedNumber"
:outputType="options.outputType"
:full="options.full"
@realTime="realTime"
>
</vue-cropper>
</el-col>
<el-col :xs="24" :md="12" :style="{height: '350px'}">
<div class="avatar-upload-preview">
<img :src="previews.url" :style="previews.img"/>
</div>
<div style="text-align: center;margin-top: 310px;">
<el-upload
accept="image/jpeg,image/gif,image/png"
action="#"
:show-file-list="false"
:auto-upload="false"
:on-change="onChange"
>
<template #default>
<el-button type="primary" icon="el-icon-folder-add">选择图片</el-button>
</template>
</el-upload>
</div>
</el-col>
</el-row>
<template #footer>
<div>
<el-button type="primary" @click="upload">上传并保存</el-button>
</div>
</template>
</el-dialog>
</template>
<script>
export default {
name: 'MyCropper',
data() {
return {
dialogVisible: false,
options: {
img: '', // 原图文件
autoCrop: true, // 默认生成截图框
fixedBox: false, // 固定截图框大小
canMoveBox: true, // 截图框可以拖动
autoCropWidth: 260, // 截图框宽度
autoCropHeight: 260, // 截图框高度
fixed: true, // 截图框宽高固定比例
fixedNumber: [1, 1], // 截图框的宽高比例
centerBox: false, // 截图框被限制在图片里面
full: true,
outputType: 'png'
},
previews: {},
}
},
methods: {
initShow(img) {
this.dialogVisible = true;
this.options.img = img;
},
realTime(data) {
this.previews = data
},
onChange(file) {
const that = this;
this.$refs['cropper'].clearCrop();
let reader = new FileReader();
reader.readAsDataURL(file.raw);
reader.onload = e => {
that.options.img = e.target.result; // base64
}
},
upload() {
const that = this
that.$refs['cropper'].getCropData((data) => {
that.$emit('saveImgUrl',data);
that.previews = {};
that.dialogVisible = false;
})
},
},
}
</script>
<style lang="scss" scoped>
.avatar-upload-preview {
position: absolute;
//margin-left: 9px;
top: 45%;
transform: translate(25%, -50%);
width: 260px;
height: 260px;
//box-shadow: 0 0 4px #ccc;
overflow: hidden;
img {
width: 100%;
height: 100%;
}
}
</style>
开发过程中一些问题总结
https://gitcode.net/mirrors/xyxiao001/vue-cropper 这是vue-cropper插件的详细API,可以看到具体参数具体用法
一个小注意点:如果el-avatar的src从后台获取图片流失败,头像框也就无法显示回显图片,但是使用上传图片裁剪功能后,saveImgUrl(data) { this.avatarPreview = data; this.form.avatar = data; },
src资源更新,但是图片仍然不显示。 解决方法是在<el-avatar :key="avatarPreview">
标签中加入key就可以了