当前位置: 首页 > article >正文

使用elementUI实现表格行拖拽改变顺序,无需引入外部库

前言:

使用vue2+element UI,且完全使用原生的拖拽事件,无需引入外部库。

如果表格数据量较大,或需要更多复杂功能,可以考虑使用 vuedraggable库,提供更多配置选项和拖拽功能。

思路:

1. 通过el-table的row-class-name设置行的自定义class类名

2. 在 mountedupdated 生命周期钩子中调用this.$nextTick,确保 DOM 元素渲染完成后,使用 document.querySelectorAll 获取所有 .drag-row 元素。

3. 设置dom的 draggable为true,并增加拖拽事件处理函数:

  • ondragstart:记录拖拽开始的索引,并设置拖拽效果。
  • ondragover:在拖拽经过时,阻止默认行为,允许放置。
  • ondrop:在拖拽放下时,交换源位置和目标位置的数据,并更新列表。

在拖拽事件内 通过 修改数据的index的方式实现 行位置的移动

  • handleDragStart 方法

    • 记录当前拖拽行的索引 draggingIndex
    • 使用 event.dataTransfer.setData 方法存储拖拽数据,方便在 ondrop 中使用。
  • handleDrop 方法

    • 获取拖拽的源索引 sourceIndex 和目标索引 targetIndex
    • 通过数组的 splice 方法删除源位置的项目,并插入到目标位置。
    • 更新组件的数据 projects,触发 Vue 的响应式更新,表格会重新渲染显示新的排序。

效果演示:

完整代码:

<template>
  <div class="sort-container">
    <span class="title">项目排序</span>
    <!-- 通过 row-class-name 为每一行动态添加行的类名 -->
    <el-table
      :data="projects"
      row-class-name="drag-row"
      @row-contextmenu.prevent
      border
    >
      <el-table-column prop="index" label="序号" width="200">
        <template slot-scope="scope">
          {{ scope.$index + 1 }}
        </template>
      </el-table-column>
      <el-table-column prop="name" label="项目名称"></el-table-column>
    </el-table>
  </div>
</template>

<script>
export default {
  data() {
    return {
      projects: [
        { id: '1', name: '男子10米气步枪' },
        { id: '2', name: '女子50米步枪三姿' },
        { id: '3', name: '男子双向飞碟' },
        { id: '4', name: '女子25米手枪' },
        { id: '5', name: '男子50米步枪卧射' },
      ],
      draggingIndex: null,// 当前正在拖拽的行索引
    };
  },
  mounted() {
    // 组件挂载后添加拖拽事件
    this.addDragEvents();
  },
  updated() {
    // 数据更新后重新添加拖拽事件
    // 使用 this.$nextTick 获取表格行的 DOM 元素
    this.$nextTick(() => {
      this.addDragEvents();
    });
  },
  methods: {
    // 添加拖拽事件
    addDragEvents() {
      // 获取所有带有类名 'drag-row' 的表格行
      const rows = document.querySelectorAll('.drag-row');
      // 遍历每一行,添加拖拽事件
      rows.forEach((row, index) => {
        row.draggable = true; // 设置行元素为可拖拽
        // 开始拖拽时的事件处理
        row.ondragstart = (event) => this.handleDragStart(event, index);
        // 拖拽经过时的事件处理
        row.ondragover = (event) => this.handleDragOver(event);
        // 拖拽放下时的事件处理
        row.ondrop = (event) => this.handleDrop(event, index);
      });
    },
    // 处理拖拽开始事件
    handleDragStart(event, index) {
      this.draggingIndex = index; // 记录当前拖拽行的索引
      event.dataTransfer.effectAllowed = 'move'; // 设置拖拽效果为移动
      event.dataTransfer.setData('text/plain', index); // 将索引存储到拖拽数据中
    },
    // 处理拖拽经过事件
    handleDragOver(event) {
      event.preventDefault(); // 阻止默认事件,允许放置
      event.dataTransfer.dropEffect = 'move'; // 设置拖拽效果为移动
    },
    // 处理拖拽放下事件
    handleDrop(event, targetIndex) {
      const sourceIndex = this.draggingIndex; // 获取开始拖拽时记录的索引

      // 如果源索引和目标索引相同,直接返回
      if (sourceIndex === targetIndex) return;

      // 创建项目列表的副本
      const projects = [...this.projects];
      // 删除源位置的项目,并存储被拖拽的项目
      const [movedItem] = projects.splice(sourceIndex, 1);
      // 在目标位置插入被拖拽的项目
      projects.splice(targetIndex, 0, movedItem);

      // 更新项目列表数据
      this.projects = projects;
      this.draggingIndex = null; // 重置拖拽索引
    },
  },
};
</script>

<style lang='scss' scoped>
.sort-container{
    padding: 15px;

    .title{
        font-size: 24px;
        font-weight: bold;
    }

    .el-table{
        margin-top: 20px;
    }
}
/* 自定义拖拽行样式 */
.drag-row {
  cursor: move;
  user-select: none;
}
.drag-row:hover {
  background-color: #f0f9ff;
}
</style>


http://www.kler.cn/a/393440.html

相关文章:

  • 如何使用ffmpeg命令行进行录屏
  • HarmonyOS 如何实现传输中的数据加密
  • docker镜像源,亲测可用,时间2024-11-14
  • 界面控件Kendo UI for Angular中文教程:如何构建带图表的仪表板?(一)
  • 《MYSQL45讲》误删数据怎么办
  • 并发基础:(淘宝笔试题)三个线程分别打印 A,B,C,要求这三个线程一起运行,打印 n 次,输出形如“ABCABCABC....”的字符串【举一反三】
  • 基于SpringBoot智慧社区管理平台
  • 力扣(LeetCode)LCR 179. 查找总价格为目标值的两个商品(Java)
  • Fabric.js中文教程
  • 唐帕科技校园语音报警系统:通过关键词识别,阻止校园霸凌事件
  • 网络基础 - 网段划分篇
  • 嵌入式硬件杂谈(一)-推挽 开漏 高阻态 上拉电阻
  • CHI 协议层 Retry —— CHI(8)
  • 安科瑞工业绝缘监测装置:保障煤矿井下6kV供电系统安全运行的关键应用——安科瑞 丁佳雯
  • Java使用Thumbnails进行图片处理
  • 《C++跨平台编译:打破系统边界,释放代码潜能》
  • pytest执行用例时从conftest.py抛出ModuleNotFoundError:No module named ‘XXX‘异常的解决办法
  • YOLOv8进阶实战:融合SAHI超推理算法,在无人机应用中精准捕捉视频与图片中的微小目标
  • 数据库运维实操优质文章文档分享(含Oracle、MySQL等) | 2024年10月刊
  • Avalonia UI 框架教程
  • Docker安装部署RabbitMQ(详细教程)
  • 【Java多线程】单例模式(饿汉模式和懒汉模式)
  • Docker 镜像和容器的导入导出及常用命令
  • 网络安全之SQL初步注入
  • Locally Linear Embedding (LLE)
  • 文件fd内容