业务需要上传封面图 要求上传图片的大小 自己参考其他文章最后实现此功能,个人收藏
效果图
vue-cropper是一个可以进行图片剪辑的插件,使用于vue
github地址:https://github.com/xyxiao001/vue-cropper
1、下载vue-cropper
npm install vue-cropper
2、引用(组件引入)
import { VueCropper } from ‘vue-cropper’
3、component引入组件
components: {
VueCropper
},
主页面代码
//上传图片
<el-upload class="avatar-uploaderCss" :action="''" :headers="MyHeader" :show-file-list="false" :before-upload="beforeAvatarUpload">
<img v-if="dataForm.coverImage" :src="dataForm.coverImage" class="avatar" />
<i v-else class="el-icon-plus avatar-uploader-icon"></i>
<!-- 裁剪功能 自己封装的组件 -->
//因为一个页面有多个上传图片 多个裁剪功能 所以用isXCropper的改变 组件监听变化 渲染调用组件
<XCropper ref="iscropper" :iscropperData="iscropperData" :isXCropper="isXCropper" @getXCropper="getXCropper"></XCropper>
js
// 裁剪功能组件引用
import XCropper from "@/components/vueCropper"
//上传
beforeAvatarUpload(file) {
let _this = this
return new Promise((resolve, reject) => {
let types = ['image/jpeg', 'image/jpg', 'image/png'];
const isJPG = types.includes(file.type)
let imgType = file.type.split("/")[1]
console.log('imgType', imgType)
const isLt2M = file.size / 1024 / 1024 < 2
if (!isJPG) {
_this.$message.error('上传图片只能是 JPG 或 png格式!')
reject()
}
if (!isLt2M) {
_this.$message.error('上传图片大小不能超过 2MB!')
reject()
}
let _URL = window.URL || window.webkitURL;
_this.iscropperData = {
img: _URL.createObjectURL(file), // 裁剪图片的地址
autoCropWidth: 319, // 默认生成截图框宽度/2
autoCropHeight: 158, // 默认生成截图框高度/2
outputType: imgType,//图片格式
fixedBox: true,
dialogVisiblex: true,
name: file.name,
fileType: '2',
file: file
}
this.isXCropper = true
})
},
// 裁剪弹窗关闭后调用
getXCropper(istype, file) {
var that = this
if (istype) {
const cloneFile = new File([file.img], file.name);
const formData = new FormData()
formData.append('file', cloneFile)
uploadFile(formData)
.then(response => {
//请求成功 不同的上传图片按钮调用不同的成功回调方法
if(file.fileType=='2'){
that.getsuccess(response.data, cloneFile)
}else if(file.fileType=='3'){
that.getsuccess2(response.data, cloneFile)
}
that.isXCropper = false
}).catch(response => {
that.$notify.error({
title: "失败",
message: response.data.msg
});
});
} else {
that.isXCropper = false
}
},
//上传成功后图片回显
getsuccess(e) {
this.dataForm.coverImage = e.data;
this.getValue();
},
封装的组件
<template>
<div class="vueCropperDIV">
<el-dialog
title="图片剪裁"
:visible.sync="dialogVisiblex"
v-model="dialogVisiblex"
:close-on-press-escape="false"
:close-on-click-modal="false"
append-to-body
width="1000px"
@close="cancel"
>
<div style="margin-top: -30px;">
<div class="cropper" style="text-align:center">
<vueCropper
ref="cropper"
:img="option.img"
:outputSize="option.outputSize"
:outputType="option.outputType"
:info="option.info"
:canScale="option.canScale"
:autoCrop="option.autoCrop"
:autoCropWidth="option.autoCropWidth"
:autoCropHeight="option.autoCropHeight"
:fixedBox="option.fixedBox"
:fixed="option.fixed"
:fixedNumber="option.fixedNumber"
:canMove="option.canMove"
:canMoveBox="option.canMoveBox"
:original="option.original"
:centerBox="option.centerBox"
:infoTrue="option.infoTrue"
:full="option.full"
:enlarge="option.enlarge"
:mode="option.mode"
>
</vueCropper>
</div>
</div>
<div style="margin-top: 10px;">
<el-button @click="cancel">取消</el-button>
<el-button type="primary" @click="finish" :loading="loading">确认</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
// 局部引用
import {VueCropper} from 'vue-cropper'
export default {
components: { VueCropper },
props: {
//所有参数
iscropperData:{
type: '',
default: null
},
//是否显示
isXCropper:{
type: Boolean,
default: false
},
},
data() {
return {
dialogVisiblex: true,
loading: false,
option: {
img: '', // 裁剪图片的地址 url 地址, base64, blob
outputSize: 1, // 裁剪生成图片的质量
outputType: 'jpeg', // 裁剪生成图片的格式 jpeg, png, webp
info: true, // 裁剪框的大小信息
canScale: true, // 图片是否允许滚轮缩放
autoCrop: true, // 是否默认生成截图框
autoCropWidth: 0, // 默认生成截图框宽度
autoCropHeight: 0, // 默认生成截图框高度
fixedBox: true, // 固定截图框大小 不允许改变
fixed: true, // 是否开启截图框宽高固定比例
fixedNumber: [1, 1], // 截图框的宽高比例 [ 宽度 , 高度 ]
canMove: true, // 上传图片是否可以移动
canMoveBox: true, // 截图框能否拖动
original: false, // 上传图片按照原始比例渲染
centerBox: true, // 截图框是否被限制在图片里面
infoTrue: true, // true 为展示真实输出图片宽高 false 展示看到的截图框宽高
full: true, // 是否输出原图比例的截图
enlarge: '1', // 图片根据截图框输出比例倍数
mode: 'contain' // 图片默认渲染方式 contain , cover, 100px, 100% auto
},
unimgurl: ''
}
},
computed: {},
watch: {
isXCropper: {
handler(newVal, oldVal) {
this.getShowModal(this.iscropperData)
},
deep: true,
immediate: true
}
},
created() {
},
mounted() { },
activated() {},
methods: {
getShowModal(obj) {
if (obj.img) {
this.option.img = obj.img
}
//裁剪生成图片的质量
if (obj.outputSize) {
this.option.outputSize = obj.outputSize
} else {
this.option.outputSize = 1
}
//裁剪生成图片的格式
if (obj.outputType) {
this.option.outputType = obj.outputType
} else {
this.option.outputType = 'jpeg'
}
//裁剪框的大小信息
if (obj.info) {
this.option.info = obj.info
} else {
this.option.info = true
}
//图片是否允许滚轮缩放
if (obj.canScale) {
this.option.canScale = obj.canScale
} else {
this.option.canScale = true
}
//是否默认生成截图框
if (obj.autoCrop) {
this.option.autoCrop = obj.autoCrop
} else {
this.option.autoCrop = true
}
//默认生成截图框宽度
if (obj.autoCropWidth) {
this.option.autoCropWidth = obj.autoCropWidth
}
//默认生成截图框高度
if (obj.autoCropHeight) {
this.option.autoCropHeight = obj.autoCropHeight
}
//固定截图框大小 不允许改变
if (obj.fixedBox) {
this.option.fixedBox = obj.fixedBox
} else {
this.option.fixedBox = false
}
//是否开启截图框宽高固定比例
if (obj.fixed) {
this.option.fixed = obj.fixed
} else {
this.option.fixed = true
}
//截图框的宽高比例
if (obj.fixedNumber) {
this.option.fixedNumber = obj.fixedNumber
} else {
this.option.fixedNumber = [this.option.autoCropWidth, this.option.autoCropHeight]
}
console.log('this.option.fixedNumber ',this.option.fixedNumber )
//上传图片是否可以移动
if (obj.canMove) {
this.option.canMove = obj.canMove
} else {
this.option.canMove = true
}
//截图框能否拖动
if (obj.canMoveBox) {
this.option.canMoveBox = obj.canMoveBox
} else {
this.option.canMoveBox = true
}
//上传图片按照原始比例渲染
if (obj.original) {
this.option.original = obj.original
}
//截图框是否被限制在图片里面
if (obj.centerBox) {
this.option.centerBox = obj.centerBox
} else {
this.option.centerBox = true
}
//true 为展示真实输出图片宽高 false 展示看到的截图框宽高
if (obj.infoTrue) {
this.option.infoTrue = obj.infoTrue
} else {
this.option.infoTrue = true
}
//是否输出原图比例的截图
if (obj.full) {
this.option.full = obj.full
} else {
this.option.full = true
}
//图片根据截图框输出比例倍数
if (obj.enlarge) {
this.option.enlarge = obj.enlarge
} else {
this.option.enlarge = '1'
}
//图片默认渲染方式
if (obj.mode) {
this.option.mode = obj.mode
} else {
this.option.mode = 'contain'
}
this.dialogVisiblex = this.isXCropper
console.log('this.dialogVisiblex0',this.dialogVisiblex)
},
finish() {
// 获取截图的数据
let that = this
this.$refs.cropper.getCropBlob(data => {
that.unimgurl = data
that.confirm()
})
},
confirm() {
var data={ img: this.unimgurl,
name:this.iscropperData.name,
fileType:this.iscropperData.fileType,
file:this.iscropperData.file
}
this.dialogVisiblex = false
//参数传给父级
this.$emit("getXCropper",true,data)
},
cancel() {
this.dialogVisiblex = false
//参数传给父级
this.$emit("getXCropper",false)
}
}
}
</script>
<style lang="scss">
.real_info_class {
.el-checkbox__input .el-checkbox__inner {
border-radius: 0;
}
}
.file-image {
width: 320px;
height: 320px;
font-size: 14px;
border: 1px solid #cccccc;
margin: 15px 0;
}
.cropper {
width: 960px;
height: 606px;
}
</style>