Element UI table顺序拖动方式是什么

发布时间:2022-08-10 09:49:49 作者:iii
来源:亿速云 阅读:324

Element UI Table 顺序拖动方式是什么

引言

在前端开发中,表格(Table)是一个非常常见的组件,用于展示和操作数据。Element UI 是一套基于 Vue.js 的桌面端组件库,提供了丰富的组件,其中 el-table 是一个非常强大的表格组件。在实际开发中,我们经常会遇到需要对表格中的行进行顺序拖动的需求,比如在任务管理、排序列表等场景中。本文将详细介绍如何在 Element UI 的 el-table 中实现顺序拖动功能,并探讨其实现原理。

1. Element UI Table 简介

Element UI 的 el-table 组件提供了丰富的功能,包括排序、筛选、分页、多选等。它支持自定义列模板、插槽、事件等,使得开发者可以灵活地定制表格的展示和交互行为。

1.1 基本用法

<template>
  <el-table :data="tableData" style="width: 100%">
    <el-table-column prop="date" label="日期" width="180"></el-table-column>
    <el-table-column prop="name" label="姓名" width="180"></el-table-column>
    <el-table-column prop="address" label="地址"></el-table-column>
  </el-table>
</template>

<script>
export default {
  data() {
    return {
      tableData: [
        {
          date: '2016-05-02',
          name: '王小虎',
          address: '上海市普陀区金沙江路 1518 弄'
        },
        {
          date: '2016-05-04',
          name: '王小虎',
          address: '上海市普陀区金沙江路 1517 弄'
        },
        {
          date: '2016-05-01',
          name: '王小虎',
          address: '上海市普陀区金沙江路 1519 弄'
        },
        {
          date: '2016-05-03',
          name: '王小虎',
          address: '上海市普陀区金沙江路 1516 弄'
        }
      ]
    }
  }
}
</script>

1.2 表格排序

Element UI 的 el-table 支持通过 sortable 属性对列进行排序。

<el-table-column prop="date" label="日期" width="180" sortable></el-table-column>

2. 顺序拖动需求分析

在实际开发中,我们可能会遇到需要对表格中的行进行顺序拖动的需求。例如,在一个任务列表中,用户可能需要通过拖动来调整任务的优先级或顺序。Element UI 的 el-table 本身并不直接支持行拖动功能,但我们可以通过结合第三方库或自定义实现来实现这一功能。

2.1 需求场景

2.2 实现思路

要实现表格行的顺序拖动,我们可以考虑以下几种方式:

  1. 使用第三方库:如 Sortable.js,这是一个功能强大的拖拽排序库,可以轻松实现元素的拖拽排序。
  2. 自定义实现:通过监听鼠标事件,手动实现拖拽排序的逻辑。

本文将重点介绍如何使用 Sortable.js 来实现 Element UI 表格的顺序拖动功能。

3. 使用 Sortable.js 实现顺序拖动

Sortable.js 是一个用于实现拖拽排序的 JavaScript 库,支持多种浏览器和设备。它可以轻松地与 Vue.js 结合使用,实现表格行的顺序拖动。

3.1 安装 Sortable.js

首先,我们需要安装 Sortable.js

npm install sortablejs --save

3.2 在 Vue 组件中使用 Sortable.js

接下来,我们可以在 Vue 组件中引入 Sortable.js,并在 mounted 钩子中初始化拖拽排序。

<template>
  <el-table :data="tableData" style="width: 100%" ref="table">
    <el-table-column prop="date" label="日期" width="180"></el-table-column>
    <el-table-column prop="name" label="姓名" width="180"></el-table-column>
    <el-table-column prop="address" label="地址"></el-table-column>
  </el-table>
</template>

<script>
import Sortable from 'sortablejs';

export default {
  data() {
    return {
      tableData: [
        {
          date: '2016-05-02',
          name: '王小虎',
          address: '上海市普陀区金沙江路 1518 弄'
        },
        {
          date: '2016-05-04',
          name: '王小虎',
          address: '上海市普陀区金沙江路 1517 弄'
        },
        {
          date: '2016-05-01',
          name: '王小虎',
          address: '上海市普陀区金沙江路 1519 弄'
        },
        {
          date: '2016-05-03',
          name: '王小虎',
          address: '上海市普陀区金沙江路 1516 弄'
        }
      ]
    }
  },
  mounted() {
    this.rowDrop();
  },
  methods: {
    rowDrop() {
      const tbody = this.$refs.table.$el.querySelector('.el-table__body-wrapper tbody');
      const _this = this;
      Sortable.create(tbody, {
        onEnd({ newIndex, oldIndex }) {
          const currRow = _this.tableData.splice(oldIndex, 1)[0];
          _this.tableData.splice(newIndex, 0, currRow);
        }
      });
    }
  }
}
</script>

3.3 代码解析

  1. 引入 Sortable.js:我们首先通过 import Sortable from 'sortablejs'; 引入 Sortable.js
  2. 获取表格的 tbody 元素:在 mounted 钩子中,我们通过 this.$refs.table.$el.querySelector('.el-table__body-wrapper tbody') 获取到表格的 tbody 元素。
  3. 初始化 Sortable:我们使用 Sortable.create 方法初始化拖拽排序,并传入 tbody 元素作为目标容器。
  4. 处理拖拽结束事件:在 onEnd 回调中,我们通过 splice 方法调整 tableData 数组的顺序,从而实现表格行的顺序拖动。

3.4 注意事项

4. 自定义实现顺序拖动

除了使用 Sortable.js,我们还可以通过自定义实现来实现表格行的顺序拖动。这种方式虽然相对复杂,但可以更灵活地控制拖拽行为。

4.1 实现思路

  1. 监听鼠标事件:通过监听 mousedownmousemovemouseup 事件来实现拖拽行为。
  2. 计算拖拽位置:在 mousemove 事件中,计算鼠标的移动距离,并更新拖拽元素的位置。
  3. 调整数据顺序:在 mouseup 事件中,根据拖拽位置调整表格数据的顺序。

4.2 代码实现

<template>
  <el-table :data="tableData" style="width: 100%" ref="table">
    <el-table-column prop="date" label="日期" width="180"></el-table-column>
    <el-table-column prop="name" label="姓名" width="180"></el-table-column>
    <el-table-column prop="address" label="地址"></el-table-column>
  </el-table>
</template>

<script>
export default {
  data() {
    return {
      tableData: [
        {
          date: '2016-05-02',
          name: '王小虎',
          address: '上海市普陀区金沙江路 1518 弄'
        },
        {
          date: '2016-05-04',
          name: '王小虎',
          address: '上海市普陀区金沙江路 1517 弄'
        },
        {
          date: '2016-05-01',
          name: '王小虎',
          address: '上海市普陀区金沙江路 1519 弄'
        },
        {
          date: '2016-05-03',
          name: '王小虎',
          address: '上海市普陀区金沙江路 1516 弄'
        }
      ],
      draggingIndex: null,
      draggingRow: null
    }
  },
  mounted() {
    this.initDrag();
  },
  methods: {
    initDrag() {
      const tbody = this.$refs.table.$el.querySelector('.el-table__body-wrapper tbody');
      const rows = tbody.querySelectorAll('tr');

      rows.forEach((row, index) => {
        row.setAttribute('data-index', index);
        row.addEventListener('mousedown', this.handleMouseDown);
      });
    },
    handleMouseDown(event) {
      const row = event.currentTarget;
      this.draggingIndex = parseInt(row.getAttribute('data-index'));
      this.draggingRow = row;

      document.addEventListener('mousemove', this.handleMouseMove);
      document.addEventListener('mouseup', this.handleMouseUp);
    },
    handleMouseMove(event) {
      const tbody = this.$refs.table.$el.querySelector('.el-table__body-wrapper tbody');
      const rows = tbody.querySelectorAll('tr');
      const rect = tbody.getBoundingClientRect();
      const offsetY = event.clientY - rect.top;

      let targetIndex = null;
      rows.forEach((row, index) => {
        const rowRect = row.getBoundingClientRect();
        if (offsetY > rowRect.top - rect.top && offsetY < rowRect.bottom - rect.top) {
          targetIndex = index;
        }
      });

      if (targetIndex !== null && targetIndex !== this.draggingIndex) {
        const rowsArray = Array.from(rows);
        const draggingRow = rowsArray[this.draggingIndex];
        const targetRow = rowsArray[targetIndex];

        if (targetIndex > this.draggingIndex) {
          tbody.insertBefore(draggingRow, targetRow.nextSibling);
        } else {
          tbody.insertBefore(draggingRow, targetRow);
        }

        this.draggingIndex = targetIndex;
      }
    },
    handleMouseUp() {
      document.removeEventListener('mousemove', this.handleMouseMove);
      document.removeEventListener('mouseup', this.handleMouseUp);

      const newTableData = [];
      const tbody = this.$refs.table.$el.querySelector('.el-table__body-wrapper tbody');
      const rows = tbody.querySelectorAll('tr');

      rows.forEach(row => {
        const index = parseInt(row.getAttribute('data-index'));
        newTableData.push(this.tableData[index]);
      });

      this.tableData = newTableData;
    }
  }
}
</script>

4.3 代码解析

  1. 初始化拖拽:在 mounted 钩子中,我们通过 initDrag 方法为每一行添加 mousedown 事件监听器。
  2. 处理鼠标按下事件:在 handleMouseDown 方法中,我们记录当前拖拽的行索引,并添加 mousemovemouseup 事件监听器。
  3. 处理鼠标移动事件:在 handleMouseMove 方法中,我们计算鼠标的位置,并根据位置调整拖拽行的位置。
  4. 处理鼠标松开事件:在 handleMouseUp 方法中,我们移除事件监听器,并根据新的行顺序更新 tableData

4.4 注意事项

5. 总结

在 Element UI 的 el-table 中实现顺序拖动功能,可以通过使用 Sortable.js 或自定义实现来完成。Sortable.js 是一个功能强大且易于使用的拖拽排序库,适合大多数场景。而自定义实现则提供了更高的灵活性,但需要处理更多的细节和边界情况。

在实际开发中,我们可以根据具体需求选择合适的实现方式。如果项目对性能要求较高,或者需要处理复杂的拖拽逻辑,可以考虑使用 Sortable.js。如果项目需要高度定制化的拖拽行为,或者对第三方库有严格的限制,可以考虑自定义实现。

无论选择哪种方式,都需要注意性能优化和兼容性问题,以确保在不同浏览器和设备上都能提供良好的用户体验。

6. 参考资料


通过本文的介绍,相信你已经掌握了在 Element UI 的 el-table 中实现顺序拖动功能的方法。希望这些内容能帮助你在实际开发中更好地应对类似的需求。如果你有任何问题或建议,欢迎在评论区留言讨论。

推荐阅读:
  1. javascript如何监听element-ui table滚动事件
  2. element-ui怎么操作table滚动效果

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

element ui table

上一篇:JavaScript设计模式之职责链模式实例分析

下一篇:Python的dict和set如何使用

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》