表格行拖拽排序

拖拽排序的功能依赖于 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;
相关推荐
NetX行者12 小时前
用 Vite + Vue3 + UnoCSS 搭建企业级项目模板(一):基础骨架
vue·vite·unocss
java水泥工19 小时前
什么是前端
java·vue·html5
mont evergreen2 天前
一封从外部世界寄来的信:二维码数据如何穿越三重门,抵达你的屏幕
electron·vue·事件
志尊宝2 天前
Vue3 零基础每日笔记(071):暗黑模式与主题切换——CSS 变量 + Element Plus 暗黑方案
前端·css·笔记·vue·html·前端开发·软件开发
guslegend3 天前
工程地基、Provider 与 ReAct 循环:Agent 核心能力的设计、实现与验收
人工智能·agent·react·架构设计·spring ai
怦然丶心动3 天前
用 Java 把干支历法算清楚:从节气切年到可读摘要
java·算法·vue·独立开发·spring boot / spring
EatFan3 天前
React 项目踩坑实录:useEffect 闭包陷阱、Context 性能陷阱与 React 18 升级避坑排查手册
前端·javascript·react.js·react·react hooks·useeffect·闭包陷阱
我最爱吃鱼香茄子5 天前
【毕业设计优选】人力资源管理系统|Java|SpringBoot|Vue|前后端分离|带详细文档+部署教学视频
java·vue·毕业设计·springboot
骑着蜗牛撵大象3276 天前
SpringBoot+Vue3 企业智能体侧挂架构:独立服务、独立数据库与主线零侵入落地
数据库·spring boot·架构·vue·springboot·事件驱动·服务拆分
码艺-Alimjan8 天前
Tauri 网站To桌面应用实战总结
前端·javascript·vue