图片拖拽参考:https://www.pianshen.com/article/78751408835/
图片上传组件
<template>
<div class="pro-pic inner-upload-single">
<transition-group tag="div" class="drag-wrap">
<div class="drag-item" v-for="(file, index) in imgFile" :key="file.Image"
draggable="true"
@dragstart="handleDragStart($event, file)"
@dragover.prevent="handleDragOver($event, file)"
@dragenter="handleDragEnter($event, file)"
@dragend="handleDragEnd($event, file)">
<div
class="img-box"
:class="{ borderColorChange:file.Image }"
@mouseenter="status.showDeleteBtn=index"
@mouseleave="status.showDeleteBtn=-1">
<el-upload
class="avatar-uploader"
action="#"
ref="uploader"
name="upfile"
:accept="accept"
:show-file-list="false"
:on-change="handleAvatarChange(index)"
:auto-upload="false"
>
<div v-if="file.Image">
<img :src="file.Image" class="avatar" ref="proPic" id="pro-pic">
</div>
<i v-else class="el-icon-plus avatar-uploader-icon">
<img src="@/assets/img/pic.png" alt="" class="img-empty"><br>
<span>点击上传</span>
</i>
</el-upload>
<div v-if="file.Image&&status.showDeleteBtn==index" class="img-cover-wrap">
<a href="javascript:;" @click.stop="del(index)" class="del-img-icon">×</a>
</div>
</div>
</div>
</transition-group>
</div>
</template>
<script>
export default {
name: "uploadMultiImage",
props: {
imgFile: {
type: Array,
default: () => []
}
},
data() {
return {
status: {
showDeleteBtn: -1
},
dragging: null
}
},
computed: {
accept() {
return 'image/jpeg,image/jpg'
}
},
methods: {
handleAvatarChange(index) {
return file => {
let params = {
file,
index
}
this.$emit('avatarChange', params)
}
},
del(index) {
this.$emit('deleteImg', index)
},
handleDragStart(e, item) {
this.dragging = item
},
handleDragEnd(e, item) {
this.dragging = null
},
handleDragOver(e) {
e.dataTransfer.dropEffect = 'move'
},
handleDragEnter(e, item) {
e.dataTransfer.effectAllowed = "move" //为需要移动的元素设置dragstart事件
if (item === this.dragging) {
return
}
const newItems = [...this.imgFile]
const src = newItems.indexOf(this.dragging)
const dst = newItems.indexOf(item)
newItems.splice(dst, 0, ...newItems.splice(src, 1))
// newItems为拖拽后的数组
console.log(newItems)
this.$emit('getDragImgFile', newItems)
}
}
}
</script>
<style lang="less" scoped>
.drag-wrap {
display: flex;
.drag-item {
margin-right: 13px;
&:last-child {
margin-right: 0;
}
}
}
.inner-upload-single {
margin-left: 10px;
}
.avatar-uploader-icon {
color: #409eff;
width: 126px;
height: 126px;
text-align: center;
vertical-align: middle;
display: table-cell;
text-align: center;
font-size: 12px;
}
.avatar {
display: block;
object-fit: scale-down;
}
#pro-pic {
width: 124px;
height: 124px;
display: block;
object-fit: scale-down;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
-webkit-transform: translate(-50%, -50%);
}
.img-empty {
vertical-align: sub;
margin-top: 10px;
margin-bottom: 10px;
}
.img-box {
width: 126px;
height: 126px;
background-color: #f9fcff;
border: dashed 1px #409eff;
float: left;
margin-right: 13px;
position: relative;
}
.img-box:last-child {
margin-right: 0;
}
.borderColorChange {
border: solid 1px #ececec;
background-color: #f9f9f9;
}
.el-icon-plus:before {
content: "";
}
// 删除
.img-cover-wrap {
background: rgba(196, 223, 248, .4);
position: absolute;
width: 100%;
height: 100%;
top: 0;
cursor: move;
.del-img-icon {
width: 24px;
height: 24px;
display: block;
background: #000000;
border-radius: 50%;
text-align: center;
line-height: 22px;
color: #ffffff;
font-size: 16px;
z-index: 10;
font-size: 20px;
right: 5px;
top: 4px;
position: absolute;
}
}
</style>
父组件
<upload-multi-image
:img-file="form.imgFile"
@avatarChange="avatarChange($event)"
@getDragImgFile="getDragImgFile($event)"
@deleteImg="deleteImg($event)"
></upload-multi-image>
data:
form:{ imgFile:[] }
methods: {
// 上传图片到阿里云
async avatarChange(e) {
if (!e.file) {
return false
}
const file = e.file
const index = e.index
let testmsg = file.name.substring(file.name.lastIndexOf('.') + 1).toLowerCase()
const isLt1M = file.size / 1024 / 1024 < 1
if (testmsg !== 'jpg' && testmsg !== 'jpeg') {
this.$message.error('上传图片只能是jpg格式!')
this.form.imgFile[index].Image = ''
return false
}
if (!isLt1M) {
this.$message.error('上传图片不能超过1M!')
this.form.imgFile[index].Image = ''
return false
}
let timestamp = Date.parse(new Date())
let res = await uploadImg()
const form = new FormData()
form.append('policy', _get(res, 'data.policy'))
form.append('OSSAccessKeyId', _get(res, 'data.accessid'))
form.append('signature', _get(res, 'data.signature'))
form.append('key', `${_get(res, 'data.dir')}${_get(res, 'data.key')}${'_'}${timestamp}${'.jpg'}`)
form.append('success_action_status', 200)
form.append('file', file.raw)
const result = await this.$http.post(process.env.OSS_URL, form)
if (result.status === 200) {
let url = (process.env.OSS_URL + '/' + `${_get(res, 'data.dir')}${_get(res, 'data.key')}${'_'}${timestamp}${'.jpg'}` + '?fr=upload')
this.form.imgFile[index].Image = url
if (this.form.imgFile.length < 5) { // 高级编辑限制5张
this.form.imgFile.push({Image: ''})
}
} else {
this.$message.error('上传失败!')
}
},
// 删除图片
deleteImg(index) {
this.form.imgFile[index].Image = ''
this.form.imgFile.splice(index,1)
if (this.form.imgFile.length < 5){
this.form.imgFile = this.form.imgFile.filter(item => item.Image) //确保只剩一个空的
this.form.imgFile.push({Image: ''})
}
},
// 获取拖拽后的图片
getDragImgFile(file) {
if (file) {
this.form.imgFile = file
}
}
}
网友评论