You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MUI X Data Grid如何添加rowDragStart、rowDragOver等自定义事件监听器?

在MUI X Data Grid中添加rowDragStart/rowDragOver事件监听

MUI X Data Grid确实没有直接暴露rowDragStart或rowDragOver这类过程性事件的props,但可以通过以下两种可靠方式实现监听:

方法一:利用Grid API订阅内部事件

这是官方推荐的方式,通过useGridApiRef获取Grid实例,订阅内部的拖拽事件:

  1. 创建apiRef并传入DataGrid组件
  2. 在useEffect中调用apiRef.current.subscribeEvent订阅目标事件,组件卸载时取消订阅
import { DataGrid, useGridApiRef } from '@mui/x-data-grid';
import { useEffect } from 'react';

function CustomDragGrid() {
  const apiRef = useGridApiRef();

  useEffect(() => {
    // 监听拖拽开始事件
    const handleRowDragStart = (params) => {
      console.log('拖拽开始,行数据:', params.row);
      // 可在这里添加自定义逻辑,比如高亮拖拽行、记录初始位置等
    };

    // 监听拖拽经过事件
    const handleRowDragOver = (params) => {
      console.log('拖拽经过目标行ID:', params.targetRowId);
      // 可在这里添加自定义逻辑,比如显示占位符、提示目标位置等
    };

    // 订阅事件,获取取消订阅函数
    const unsubscribeStart = apiRef.current.subscribeEvent('rowDragStart', handleRowDragStart);
    const unsubscribeOver = apiRef.current.subscribeEvent('rowDragOver', handleRowDragOver);

    // 组件卸载时清理订阅
    return () => {
      unsubscribeStart();
      unsubscribeOver();
    };
  }, [apiRef]);

  const columns = [
    { field: 'id', headerName: 'ID', width: 70 },
    { field: 'name', headerName: '姓名', width: 130 },
    { field: 'age', headerName: '年龄', width: 90 }
  ];

  const rows = [
    { id: 1, name: '张三', age: 25 },
    { id: 2, name: '李四', age: 30 },
    { id: 3, name: '王五', age: 28 }
  ];

  return (
    <div style={{ height: 400, width: '100%' }}>
      <DataGrid
        apiRef={apiRef}
        rows={rows}
        columns={columns}
        rowDragEnabled // 必须开启行拖拽功能
      />
    </div>
  );
}

方法二:直接监听DOM拖拽事件(底层控制)

如果需要更底层的DOM级控制,可以监听DataGrid容器的原生拖拽事件,通过类名判断是否为行拖拽触发:

import { DataGrid } from '@mui/x-data-grid';
import { useEffect, useRef } from 'react';

function DomDragGrid() {
  const gridRef = useRef(null);

  useEffect(() => {
    const gridContainer = gridRef.current?.parentElement;

    const handleDragStart = (e) => {
      // 验证是否为行拖拽图标触发的事件
      if (e.target.closest('.MuiDataGrid-rowDragIcon')) {
        const rowEl = e.target.closest('.MuiDataGrid-row');
        const rowId = rowEl?.dataset.id;
        console.log('DOM拖拽开始,行ID:', rowId);
      }
    };

    const handleDragOver = (e) => {
      e.preventDefault(); // 必须阻止默认行为才能允许后续drop操作
      const rowEl = e.target.closest('.MuiDataGrid-row');
      if (rowEl) {
        const targetRowId = rowEl.dataset.id;
        console.log('DOM拖拽经过,目标行ID:', targetRowId);
      }
    };

    // 添加DOM事件监听
    gridContainer?.addEventListener('dragstart', handleDragStart);
    gridContainer?.addEventListener('dragover', handleDragOver);

    // 卸载时移除监听
    return () => {
      gridContainer?.removeEventListener('dragstart', handleDragStart);
      gridContainer?.removeEventListener('dragover', handleDragOver);
    };
  }, []);

  // 列和行数据同方法一
  const columns = [/* 你的列配置 */];
  const rows = [/* 你的行数据 */];

  return (
    <div style={{ height: 400, width: '100%' }}>
      <DataGrid
        ref={gridRef}
        rows={rows}
        columns={columns}
        rowDragEnabled
      />
    </div>
  );
}

关于onRowOrderChange无效的说明

onRowOrderChange仅在拖拽完成且行顺序确实发生改变时才会触发,它是一个最终结果回调,而非拖拽过程中的事件,所以无法用来监听rowDragStart或rowDragOver这类过程性动作。

内容的提问来源于stack exchange,提问作者Tech News

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 15:25:15