如何为带粘性表头的MUI DataGrid实现滚动阴影效果?
实现MUI DataGrid滚动阴影效果(粘性表头版)
核心思路
监听DataGrid内部滚动容器的滚动事件,根据滚动位置动态切换容器类名,通过CSS控制表头下方和表格底部的阴影显示逻辑。
实现步骤
1. 定义阴影样式
先写好对应的CSS类,分别控制不同状态下的阴影:
/* 顶部状态:仅表头下方显示阴影 */ .datagrid-top-shadow .MuiDataGrid-columnHeaders { box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); } /* 底部状态:仅表格底部显示阴影 */ .datagrid-bottom-shadow .MuiDataGrid-virtualScroller { box-shadow: 0 -2px 4px rgba(0, 0, 0, 0.1); } /* 中间状态:同时显示上下阴影 */ .datagrid-both-shadow .MuiDataGrid-columnHeaders { box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); } .datagrid-both-shadow .MuiDataGrid-virtualScroller { box-shadow: 0 -2px 4px rgba(0, 0, 0, 0.1); }
2. 编写带滚动监听的DataGrid组件
用useRef获取Grid实例,监听滚动容器的scroll事件,判断位置后切换类名:
import { DataGrid } from '@mui/x-data-grid'; import { useEffect, useRef, useState } from 'react'; const ScrollShadowDataGrid = ({ columns, rows }) => { const gridRef = useRef(null); const [shadowClassName, setShadowClassName] = useState('datagrid-top-shadow'); useEffect(() => { // 获取DataGrid的滚动容器 const scrollContainer = gridRef.current?.element?.querySelector('.MuiDataGrid-virtualScroller'); if (!scrollContainer) return; const checkScrollPosition = () => { const { scrollTop, scrollHeight, clientHeight } = scrollContainer; // 滚动到顶部 if (scrollTop === 0) { setShadowClassName('datagrid-top-shadow'); } // 滚动到底部(减1处理精度误差) else if (scrollTop + clientHeight >= scrollHeight - 1) { setShadowClassName('datagrid-bottom-shadow'); } // 中间位置 else { setShadowClassName('datagrid-both-shadow'); } }; // 添加滚动监听 scrollContainer.addEventListener('scroll', checkScrollPosition); // 初始化时执行一次,确保初始状态正确 checkScrollPosition(); // 组件卸载时移除监听 return () => scrollContainer.removeEventListener('scroll', checkScrollPosition); }, []); return ( <div className={shadowClassName}> <DataGrid ref={gridRef} columns={columns} rows={rows} stickyHeader // 必须开启粘性表头 // 其他自定义配置 /> </div> ); }; export default ScrollShadowDataGrid;
3. 注意事项
- 必须开启
stickyHeader属性,否则表头不会固定,顶部阴影逻辑不成立。 - 阴影样式可根据需求调整
box-shadow的参数,比如修改阴影颜色、模糊半径、偏移量。 - 滚动判断时的
scrollHeight - 1是为了兼容浏览器滚动的精度问题,避免因为像素小数导致无法触发底部状态。
内容的提问来源于stack exchange,提问作者Jöcker
相关产品推荐
相关产品推荐

