MUI X Data Grid如何添加rowDragStart、rowDragOver等自定义事件监听器?
在MUI X Data Grid中添加rowDragStart/rowDragOver事件监听
MUI X Data Grid确实没有直接暴露rowDragStart或rowDragOver这类过程性事件的props,但可以通过以下两种可靠方式实现监听:
方法一:利用Grid API订阅内部事件
这是官方推荐的方式,通过useGridApiRef获取Grid实例,订阅内部的拖拽事件:
- 创建
apiRef并传入DataGrid组件 - 在
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
相关产品推荐
相关产品推荐

