使用到的插件:vuedraggable 官方文档:vue.draggable.next 中文文档 - itxst.com
逻辑方面:根据elementPlus 做一个“伪”上传组件,隐藏原有的el-upload 。这样一来,draggable就可以操作包含在里面的“伪”上传组件了
1.按照vuedraggable
yarn add vuedraggable@next
npm i -S vuedraggable@next
2.在所需页面引入
import draggable from "vuedraggable";
3.绘制页面
html:
<div class="upload">
<div class="title">上传5张头图(340*210px) 请按顺序上传:第一张为正面、第二张为45°,第三张为背面,第四张为内饰,第五张为后排座椅</div>
<div>
<draggable :list="album" ghost-class="ghost" chosen-class="chosenClass" animation="200">
<template #item="{ element }">
<ul class="el-upload-list el-upload-list--picture-card">
<li :key="element" class="el-upload-list__item is-success animated">
<img :src="element" alt="" class="el-upload-list__item-thumbnail ">
<label class="el-upload-list__item-status-label">
<i class="el-icon el-icon--upload-success el-icon--check">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024">
<path fill="currentColor"
d="M406.656 706.944 195.84 496.256a32 32 0 1 0-45.248 45.248l256 256 512-512a32 32 0 0 0-45.248-45.248L406.592 706.944z">
</path>
</svg></i></label>
<i class="el-icon-close"></i>
<span class="el-upload-list__item-actions">
<!-- 预览 -->
<span class="el-upload-list__item-preview"
@click="handlePictureCardPreviewFileDetail(element)">
<i class="el-icon el-icon--zoom-in">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024">
<path fill="currentColor"
d="m795.904 750.72 124.992 124.928a32 32 0 0 1-45.248 45.248L750.656 795.904a416 416 0 1 1 45.248-45.248zM480 832a352 352 0 1 0 0-704 352 352 0 0 0 0 704zm-32-384v-96a32 32 0 0 1 64 0v96h96a32 32 0 0 1 0 64h-96v96a32 32 0 0 1-64 0v-96h-96a32 32 0 0 1 0-64h96z">
</path>
</svg>
</i>
</span>
<!-- 删除 -->
<span class="el-upload-list__item-delete" @click="handleRemoveFileDetail(element)">
<i class="el-icon el-icon--zoom-in">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024">
<path fill="currentColor"
d="M160 256H96a32 32 0 0 1 0-64h256V95.936a32 32 0 0 1 32-32h256a32 32 0 0 1 32 32V192h256a32 32 0 1 1 0 64h-64v672a32 32 0 0 1-32 32H192a32 32 0 0 1-32-32V256zm448-64v-64H416v64h192zM224 896h576V256H224v640zm192-128a32 32 0 0 1-32-32V416a32 32 0 0 1 64 0v320a32 32 0 0 1-32 32zm192 0a32 32 0 0 1-32-32V416a32 32 0 0 1 64 0v320a32 32 0 0 1-32 32z">
</path>
</svg>
</i>
</span>
</span>
</li>
</ul>
</template>
</draggable>
</div>
<el-upload v-model:file-list="bannerList" :show-file-list="false"//隐藏原来的上传组件 accept=".jpeg,.png,.jpg,.bmp,.gif"
:before-upload="checkFileType" :on-remove="removeAlbum" :limit="5" list-type="picture-card"
:on-preview="handlePictureCardPreview" :http-request="uploadBanner">
<el-icon>
<Plus />
</el-icon>
</el-upload>
</div>
<!-- 预览图 -->
<el-dialog v-model="dialogVisible">
<img w-full :src="dialogImageUrl" alt="Preview Image" />
</el-dialog>
ts:
//---------------上传图片
const dialogVisible = ref(false)//预览弹框
const dialogImageUrl = ref('')
const bannerList = ref<UploadUserFile[]>([])//原本el-upload组件中的数据
//上传前 检测
const checkFileType = (file: any) => {
const fileType = file.name.substring(file.name.lastIndexOf('.'))
const isImage =
fileType === '.jpg' ||
fileType === '.png' ||
fileType === '.jpeg' ||
fileType === '.bmp' ||
fileType === '.gif'
if (!isImage)
ElMessageBox({
title: '温馨提示',
message: '上传文件只能是 jpg / png /jpeg / bmp 格式!',
type: 'warning',
});
return isImage
}
//上传头图
const isSuccess = ref(false)
const album = ref<string[]>([]) //后端所需要的数据
const uploadBanner = async (param: UploadRequestOptions) => {
const res = await reqUploadPdf(param.file) //自己封装的上传文件api
if (res.code !== 0) return ElMessage.error(res.message)
ElMessage.success('上传成功')
isSuccess.value = true
album.value.push(res.data.url)
}
// 预览
const handlePictureCardPreviewFileDetail = (file: string) => {
dialogImageUrl.value = file;
dialogVisible.value = true;
}
// 删除
const handleRemoveFileDetail = (val: string) => {
bannerList.value.splice(album.value.findIndex(item => item === val), 1)
album.value = album.value.filter(item => item !== val)
}
欢迎斧正