vue3+ts 实现el-upload 可拖拽排序 (直接cv就能用)

使用到的插件: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)
}

欢迎斧正

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值