ElementUI多图拖拽
准备
yarn add vuedraggable
or
npm i -S vuedraggable
代码示例
<template>
<div>
<el-row style="margin-top: 20px;">
<el-col :span="20" :offset="2">
<el-form-item label="预览" prop="desc">
<div class="image-list">
<draggable v-model="showImgList" @change="dragChange">
<div v-for="(image, index) in showImgList" :key="index" class="image-wrap">
<img :src="image" :style="imgStyle" />
<div class="icon-wrap" @click.stop="removeFile(index)">
<i class="el-icon-delete"></i>
</div>
</div>
<el-upload
ref="imageListUpload"
:action="$uploadPicUrl"
:headers="header"
:before-upload="beforeUpload"
:on-success="uploadSuccess"
class="image-uploader"
:on-error="onError"
multiple
:show-file-list="false"
accept="image/*">
<i :class="loading ? 'el-icon-loading' : 'el-icon-plus'" :style="imgStyle"></i>
</el-upload>
</draggable>
</div>
</el-form-item>
</el-col>
</el-row>
</div>
</template>
<style>
.ql-container .ql-editor{
height:400px;
}
.avatar-uploader .el-upload {
height: 180px;
width: 180px;
overflow: hidden;
}
.avatar-uploader img {
height: 180px;
width: 180px;
}
.avatar-uploader .avatar-uploader-icon {
border: 1px dashed #d9d9d9;
border-radius: 6px;
cursor: pointer;
font-size: 28px;
color: #8c939d;
width: 178px;
height: 178px;
line-height: 178px;
text-align: center;
}
#video .video {
max-width: 300px;
max-height: 200px;
}
.avatar {
width: 178px;
height: 178px;
display: block;
}
.avatar-uploader img {
height: 180px;
width: 180px;
}
.ql-editor{
height:400px;
}
.ql-snow .ql-picker {
height: auto;
}
.image-list,
.image-item {
display: flex;
}
.image-list .image-wrap,
.image-item .image-wrap {
position: relative;
display: inline-block;
box-sizing: content-box;
margin: 0 8px 8px 0;
vertical-align: top;
}
.image-list .image-wrap:hover .icon-wrap,
.image-item .image-wrap:hover .icon-wrap {
opacity: 1;
}
.image-list .image-wrap .icon-wrap,
.image-item .image-wrap .icon-wrap {
position: absolute;
left: 0;
bottom: 0;
width: 100%;
height: 30px;
cursor: default;
text-align: center;
color: #fff;
opacity: 0;
font-size: 20px;
background-color: rgba(0, 0, 0, 0.7);
transition: opacity .3s;
}
.image-list .image-wrap .icon-wrap .el-icon-zoom-in,
.image-item .image-wrap .icon-wrap .el-icon-zoom-in {
cursor: pointer;
margin-right: 8px;
}
.image-list .image-wrap .icon-wrap .el-icon-delete,
.image-item .image-wrap .icon-wrap .el-icon-delete {
cursor: pointer;
}
.image-item {
display: inline-flex;
}
.image-uploader {
display: inline-block;
}
.image-uploader .el-upload {
border: 1px dashed #d9d9d9;
border-radius: 6px;
cursor: pointer;
position: relative;
overflow: hidden;
}
.image-uploader .el-upload [class^="el-icon"] {
font-size: 28px;
color: #8c939d;
text-align: center;
}
.image-uploader .el-upload:hover {
border-color: #409EFF;
}
</style>
<script>
import draggable from 'vuedraggable'
export default {
components: {
draggable,
},
data() {
return {
showImgList: [],
loading: false,
}
},
created() {
if (this.$route.params.id > 0) {
this.getInfo(this.$route.params.id)
this.goodsForm.id = this.$route.params.id;
} else {
this.responseVisible = false;
}
},
computed: {
imgStyle() {
return {
width: '180px',
height: '180px',
lineHeight: '180px',
}
}
},
mounted() {
// 为图片ICON绑定事件 getModule 为编辑器的内部属性
// this.$refs.myQuillEditor.quill.getModule('toolbar').addHandler('image', this.imgHandler)
// this.$refs.myQuillEditor.quill.getModule('toolbar').addHandler('video', this.insertVideo) // 为视频ICON绑定事件
},
methods: {
beforeUpload(file) {
if (file.type.split('/')[0] === 'image') {
let tempSize = file.size / 1024 / 1024 / 2;
if (tempSize > 1) {
this.$message.error('图片尺寸不得大于2M!');
return false;
}
} else {
this.$message.error('请上传图片格式(jpg、png、gif)');
return false;
}
},
getInfo(id) {
var _self = this;
projectInfo(id).then(function(res){
_self.goodsForm = res.data.data;
_self.goodsForm.start_time = timestampToDate(_self.goodsForm.start_time);
_self.goodsForm.over_time = timestampToDate(_self.goodsForm.over_time);
_self.showImgList = _self.goodsForm.desc.split("|");
_self.responseVisible = false;
}).catch(function(error){
console.log(error);
})
},
handleRemove(file, fileList) {
console.log(file, fileList);
},
uploadSuccess(response, file, fileList) {
try {
for (let fileInfo of fileList) {
if (this.type === 'image') {
this.imgUrl = response.key
this.$emit('update:data', response.key)
} else {
if (this.showImgList.length >= this.limit) { // 限制图片张数
this.showImgList.length = this.limit
throw(new Error(`最多上传 ${this.limit} 张图片`))
}
this.showImgList.push(response.data.filepath)
this.$emit('update:data', this.showImgList)
}
}
} catch (error) {
this.$message.error(error.message)
} finally {
this.loading = false
this.$refs.imageListUpload && this.$refs.imageListUpload.clearFiles()
this.$refs.imageUpload && this.$refs.imageUpload.clearFiles()
}
},
removeFile(index) {
this.$confirm('确定删除该图片吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
if (this.type === 'image') {
this.$emit('update:data', typeof this.data === 'object' ? {} : '')
} else {
this.showImgList.splice(index, 1)
this.$emit('update:data', this.showImgList)
}
})
},
onError() {
this.$message.error('上传文件失败')
},
dragChange(ele) {
console(ele.moved)
},
handleRemove(file, fileList) {
let imgList = fileList.map(item => {
return item.response.key
})
this.$emit('update:data', imgList)
},
}
}
</script>
注意务必注册引入组件
import draggable from 'vuedraggable'
export default {
...
components: {
draggable,
},
...
ElementUI多图拖拽
https://blog.puresai.com/2020/02/27/228/