前军教程网

中小站长与DIV+CSS网页布局开发技术人员的首选CSS学习平台

产品:上传图片拖拽一下怎么了 ?

前戏

一、需求背景:一个产品经理的执念

"小X啊,这个商品详情页的图片要能拖动排序,就像手机相册那样丝滑!"

—— 来自产品经理的第7次需求变更

作为前端炒粉,面对这个"简单"需求时,我望着Element Plus官方文档陷入了沉思 。el-upload组件虽然能完美处理上传,但原生并不支持已上传图片的拖拽排序。于是,当然是选择满足他啦...

一、需求背景

言归歪传,在管理后台开发中,经常需要实现图片上传与排序功能。Element Plus 的 el-upload 组件虽然提供了基础的图片上传功能,但原生并不支持已上传图片的拖拽排序。下面将基于 el-upload 组件,结合 HTML5拖放 API,实现图片上传后的拖拽排序的基本功能。


#技术分享二、实现效果

  1. 上传后的图片支持拖拽交换位置
  2. 实时预览拖拽后的排序效果

三、核心实现分析:魔法背后的秘密

1. 模板结构解析

<el-upload
  list-type="picture-card"
  :auto-upload="false"
  :limit="10"
  v-model:file-list="userInfo.pictureMobile"
  :on-change="handleChange"

>

<template #file="{ file }">

<div draggable="true" <!-- 开启拖拽功能 -->

@dragstart="handleDragStart($event,file,'mb')" @drop="handleDrop($event,file,'mb')" @dragover.prevent>

<img :src="file.url" />

<span class="el-upload-list__item-actions">

<span @click="handlePictureCardPreview(file)">

<el-icon><zoom-in /></el-icon>

</span>

<span @click="handleRemove(file,'mb')">

<el-icon><Delete /></el-icon>

</span>

</span>

</div>

</template>

</el-upload>

2. 逻辑实现

拖拽二部曲 →

第一步:拖拽开始事件处理:dragstart

  • 获取当前拖拽项的索引
  • 将索引存入数据传输对象
const handleDragStart = (event, file, type: string) => {

  const imgList = userInfo.picturePc;

  const index = imgList.findIndex(element => element === file);

event.dataTransfer.setData('index', index.toString()); }

第二步:拖拽释放事件处理:handleDrop

  • 获取目标位置索引
  • 阻止默认行为
  • 获取拖拽源索引
  • 创建数组副本(保证响应式更新)
  • 执行数组元素移动
  • 更新图片列表
const handleDrop = (event, file, type) => {

  const index = imgList.findIndex(element => element === file);


  event.preventDefault();

const draggedIndex = Number(event.dataTransfer.getData('index')); const updatedList = [...imgList]; const [draggedItem] = updatedList.splice(draggedIndex, 1); updatedList.splice(index, 0, draggedItem);

userInfo.picturePc = updatedList }

四、关键点

HTML 1. HTML5拖放API

  • draggable="true" :使元素可拖拽
  • @dragstart :拖拽开始时触发
  • @drop :拖拽释放时触发
  • @dragover.prevent :阻止默认拖拽行为
  • dataTransfer :跨事件数据传输对象

2. 数组操作技巧

const updatedList = [...originalList];
const [movedItem] = updatedList.splice(oldIndex, 1);
updatedList.splice(newIndex, 0, movedItem);

3. 响应式更新

通过创建数组副本并重新赋值,触发 Vue 的响应式更新:

userInfo.pictureMobile = updatedList

五、踩坑日记:程序员的自我修养

坑1:幽灵图片问题

现象 :拖拽时出现半透明残影 解法 :给拖拽元素添加 CSS 样式

.dragging-item {
  opacity: 0.5;
  transform: rotate(3deg);
}

坑2:移动端兼容性

现象 :手机滑动触发页面滚动 解法 :添加 touch-action 样式

.mobile-container {
  touch-action: none;
}

六、完整实现流程

  1. 初始化el-upload组件,禁用自动上传
  2. 通过file-list绑定图片数据源
  3. 自定义文件项模板,添加拖拽事件
  4. 实现拖拽开始时的索引记录
  5. 处理拖拽释放时的元素交换)
  6. 更新响应式数据触发视图刷新

七、总结

通过结合 el-upload 的文件管理能力和 HTML5原生拖放 API,简单实现了直观的图片拖拽排序功能。

这种方案具有以下优势:

| 优势 | 说明 | | ---

| 轻量级 | 无需额外依赖库 | | 高兼容 | 基于原生 API 实现 | | 易扩展 | 支持多场景类型参数 |

**下次再见!

**

发表评论:

控制面板
您好,欢迎到访网站!
  查看权限
网站分类
最新留言