背景:产品提了一个需求,动态上传banner图片且支持拖拽排序
HTML
<draggable v-model="uploadObj.fileList" sort="true" chosenClass="chosen" forceFallback="true" group="people" animation="1000" @end="onEnd">
<transition-group>
<div class="item" v-for="(element,index) in uploadObj.fileList" :key="index">
<img :src="uploadPath+element.url" alt="" class="el-upload-list__item-thumbnail "/>
<div class="hover-wrap">
<span class="bg-black" />
<div class="btn-group">
<span class="el-upload-list__item-preview" @click="handlePicturePreview(element)">
<i class="el-icon-zoom-in"></i>
</span>
<span class="el-upload-list__item-delete" @click="handleRemove(index)">
<i class="el-icon-delete"></i>
</span>
</div>
</div>
</div>
</transition-group>
</draggable>
<el-upload
class="avatar-uploader"
list-type="picture-card"
:limit="5"
:multiple="true"
:action="uploadObj.path"
:data="uploadObj.data"
:show-file-list="false"/*隐藏element图片列表*/
:drag="true"
:file-list="uploadObj.fileList"
:on-success="handleSuccess"
:before-upload="beforeAvatarUpload"
:on-exceed="handleExceed"
accept=".jpg,.jpeg,.png">
<i class="el-icon-plus"></i>
</el-upload>
<!-- 预览弹出层 -->
<el-dialog :visible.sync="uploadObj.dialogVisibleDetail">
<img width="100%" :src="uploadObj.dialogImageDetailUrl" alt="">
</el-dialog>
JS
import draggable from 'vuedraggable'
export default {
components: {draggable},
data(){
uploadObj: { // 上传图片配置
path: 'XXXX', // 地址
data: { // 附带参数
path: 'upload/'
},
fileList:[],
dialogVisibleDetail:false,
dialogImageDetailUrl:'',
},
},
methods:{
// 上传前
beforeAvatarUpload(file) {
const reg = /\.(png|jpg|jpeg)(\?.*)?$/
if (!reg.test(file.name)) {
this.$message.error('请上传正确的图片格式')
return false
}
const isLt1M = file.size / 1024 / 1024 < 4
if (!isLt1M) {
this.$message.error('图片大小不能超过 4MB!')
}
return isLt1M
},
handleExceed(files, fileList){
this.$message.warning(`当前限制选择 5 张图片,本次选择了 ${files.length} 张图片,共选择了 ${files.length + fileList.length} 张图片`);
},
// 顶部banner上传成功
handleSuccess(res) {
this.uploadObj.fileList.push({
url:res.data
});
},
// 放大
handlePicturePreview(file) {
this.uploadObj.dialogImageDetailUrl = this.uploadPath+file.url;
this.uploadObj.dialogVisibleDetail = true;
},
// 删除
handleRemove(index) {
this.uploadObj.fileList.splice(index, 1);
},
//拖拽结束事件
onEnd(e) {
const picList = []
this.uploadObj.fileList.forEach(item=>{
picList.push(item.url)
})
console.log(picList);//排序后的图片数组
},
}
}
scss:
.item{
position: relative;
width: 178px;
height: 178px;
display: inline-block;
margin-right: 15px;
margin-bottom: 15px;
border-radius: 5px;
overflow: hidden;
.hover-wrap{
display:none
}
&:hover{
.hover-wrap{
display:block
}
}
.bg-black{
background:rgba(96, 98, 102, 0.3);
width: 100%;
height: 100%;
position: absolute;
left: 0;
top: 0;
}
.btn-group{
position: absolute;
left: 0;
top: 45%;
width: 100%;
display: flex;
justify-content: center;
.el-upload-list__item-preview,
.el-upload-list__item-delete{
color: #fff;
font-size: 20px;
display: block;
margin: 0 10px;
}
.el-upload-list__item-delete{
position: static;
}
}
}