表格行拖拽排序

拖拽排序的功能依赖于 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;
相关推荐
csdn2015_5 小时前
nodejs安装
node.js·vue
名字还没想好☜1 天前
React setState 连续调用「丢更新」排查:批量更新与函数式更新
前端·javascript·react.js·react·usestate
sugar__salt1 天前
DeepSeek-R1 WebGPU (1):在浏览器里跑大模型
react.js·reactjs·react·端模型
minhuan2 天前
大模型Agent核心架构,详解ReAct、Plan-and-Execute、Reason-Act-Observe循环21.6
react·大模型应用·agent架构·ai应用架构设计·plan-execute
名字还没想好☜2 天前
React useLayoutEffect vs useEffect:页面闪一下的元凶与正确修法
前端·javascript·react.js·react·hooks
jieyucx2 天前
Nuxt4阶段一:环境搭建与第一个 Nuxt 4 项目
vue·nuxt·全栈·ssr
小堂子这厢有礼了3 天前
Chet.Admin 模块详解②:用户管理与个人中心
vue·rbac·后台管理系统·用户权限·.net10·vbenadmin
sugar__salt3 天前
Vue.js 前置知识:ES6+ 核心特性完全指南
前端·javascript·vue.js·vue·es6
sugar__salt3 天前
Vue3 基础知识点整理 —— 从入门到响应式核心完全指南
vue.js·笔记·vue·vue3
钛态5 天前
前端安全防线:CSRF 攻击链路与双重 Token 校验的工程实现
前端·vue·react·web