表格行拖拽排序

拖拽排序的功能依赖于 sortablejs 库,需要先安装这个库

这边安装的是 1.12.0 版本的,可以正常使用

完整版的实例可以看当前目录下的 TableDrag.vue

1 安装 sortablejs

js 复制代码
// 普通安装
npm install sortablejs --save

// 安装指定版本(建议安装此版本)
npm install sortablejs@1.12.0 --save

2 vue示例

html 复制代码
<template>
  <div class="table-drag-demo">
    <!-- 按钮 -->
    <div class="top-btns">
      <el-button type="primary" size="medium" @click="startDrag">开启拖拽</el-button>
      <el-button type="primary" size="medium" @click="endDrag">关闭拖拽</el-button>
    </div>

    <!-- 表格 -->
    <el-table :data="tableData" border row-key="id">
      <el-table-column prop="id" align="center" label="ID" width="55"></el-table-column>
      <el-table-column prop="name" align="center" label="名称"></el-table-column>
      <el-table-column prop="age" align="center" label="主页地址"></el-table-column>
    </el-table>
  </div>
</template>

<script>
  // 表格拖拽排序组件
  import Sortable from "sortablejs";
  export default {
    name: "TableDrag",
    data() {
      return {
        tableData: [], // 表格数据
        sortable: {}, // Sortable实例
      };
    },
    created() {
      // mock数据
      let arr = [];
      for (let i = 0; i < 5; i++) {
        arr.push({
          id: i,
          name: `学生 - ${i}`,
          age: i + 10,
        });
      }
      this.tableData = arr;
    },
    mounted() {
      this.initSort(); // 组件挂载,初始化Sortable
    },
    methods: {
      // 初始化拖拽
      initSort() {
        let tbody = document.querySelector(".el-table__body-wrapper tbody");
        let _this = this;
        this.sortable = Sortable.create(tbody, {
          disabled: true, // 设置为true,默认不允许拖拽,设置为false的时候,就是默认开启拖拽
          onEnd({ newIndex, oldIndex }) {
            const currRow = _this.tableData.splice(oldIndex, 1)[0];
            _this.tableData.splice(newIndex, 0, currRow);
          },
        });
      },
      // 开始拖拽
      startDrag() {
        // let state = this.sortable.option("disabled"); // 获取是否禁止拖拽,true为禁止,false为启用
        this.sortable.option("disabled", false);
      },
      // 关闭拖拽
      endDrag() {
        this.sortable.option("disabled", true);
      },
    },
  };
</script>

<style lang="scss" scoped>
  .table-drag-demo {
    padding: 15px;
    .top-btns {
      margin-bottom: 15px;
    }
  }
</style>

3 react示例

js 复制代码
import { useEffect, useRef } from "react";
import { Table, Row, Button, Space } from "antd";
import Sortable from "sortablejs";

const columns = [
  {
    title: "Name",
    dataIndex: "name",
    key: "name",
  },
  {
    title: "Age",
    dataIndex: "age",
    key: "age",
  },
  {
    title: "Address",
    dataIndex: "address",
    key: "address",
  },
];

const data = [
  {
    key: "1",
    name: "1 John Brown",
    age: 11,
    address: "New York No. 1 Lake Park",
  },
  {
    key: "2",
    name: "2 Jim Green",
    age: 22,
    address: "London No. 1 Lake Park",
  },
  {
    key: "3",
    name: "3 Joe Black",
    age: 33,
    address: "Sidney No. 1 Lake Park",
  },
];

const TableDrag = () => {
  // Ref
  const sortableRef = useRef(null);
  const dataSourceRef = useRef(data); // 注意:dataSource必须使用ref,不能使用state,state会导致更新不同步,拖拽异常

  // 初始化
  useEffect(() => {
    initSort();
  }, []);

  // 初始化拖拽
  const initSort = () => {
    const tbody = document.querySelector(".ant-table .ant-table-tbody");
    sortableRef.current = Sortable.create(tbody, {
      disabled: false, // true为不允许拖拽,false为允许拖拽
      onEnd({ newIndex, oldIndex }) {
        const currRow = dataSourceRef.current.splice(oldIndex, 1)[0];
        dataSourceRef.current.splice(newIndex, 0, currRow);
      },
    });
  };
  // 开启拖拽
  const startDrag = () => {
    // let state = sortableRef.current?.option("disabled"); // 获取是否禁止拖拽,true为禁止,false为启用
    // 配置项手册:http://www.sortablejs.com/options.html
    sortableRef.current?.option("disabled", false);
  };
  // 关闭拖拽
  const endDrag = () => {
    sortableRef.current?.option("disabled", true);
  };
  // 打印数据
  const printData = () => {
    console.log(dataSourceRef.current);
  };

  return (
    <div>
      <Table columns={columns} dataSource={data} pagination={false} />
      <Row justify="center" style={{ marginTop: "20px" }}>
        <Space>
          <Button type="primary" onClick={startDrag}>
            开启拖拽
          </Button>
          <Button type="primary" onClick={endDrag}>
            关闭拖拽
          </Button>
          <Button type="primary" onClick={printData}>
            打印数据
          </Button>
        </Space>
      </Row>
    </div>
  );
};

export default TableDrag;
相关推荐
吐个泡泡v19 小时前
AI Agent 核心认知框架详解
react·cot·ai agent·认知框架
~无忧花开~19 小时前
React组件与Props完全指南
开发语言·前端·react
yusheng_xyb19 小时前
使用TypeScript与React构建高效用户界面
typescript·react·前端开发
木斯佳20 小时前
前端八股文面经大全:阿里云AI应用开发二面(2026-03-21)·面经深度解析
前端·css·人工智能·阿里云·ai·面试·vue
胡少侠72 天前
ReAct Agent:手写 Thought-Action-Observe 循环,从工具调用到真正的 Agent
ai·agent·react·rag
工业互联网专业2 天前
基于Python的黑龙江旅游景点数据分析系统的实现_flask+spider
python·flask·vue·毕业设计·源码·课程设计·spider
大叔_爱编程2 天前
基于协同过滤算法的理财产品推荐系统-flask
python·flask·vue·毕业设计·源码·课程设计·协同过滤
小彭努力中2 天前
193.Vue3 + OpenLayers 实战:圆孔相机模型推算卫星拍摄区域
vue.js·数码相机·vue·openlayers·geojson
小彭努力中2 天前
192.Vue3 + OpenLayers 实战:点击地图 Feature,列表自动滚动定位
vue·webgl·openlayers·geojson·webgis
百锦再3 天前
Vue不是万能的:前后端不分离开发的优势
前端·javascript·vue.js·前端框架·vue