如何将Material UI makeStyles转Emotion?求可调整抽屉代码转换示例
可调整大小的Material UI 5抽屉(Emotion版本)
下面是转换后的完整代码,替换原makeStyles为Emotion的styled API,适配Material UI 5:
import React, { useState, useRef, useEffect } from 'react'; import styled from '@emotion/styled'; import { Drawer as MuiDrawer } from '@mui/material'; // 基于MUI Drawer扩展样式 const Drawer = styled(MuiDrawer)` .MuiDrawer-paper { position: relative; overflow: hidden; } `; // 自定义抽屉容器,支持动态宽度 const DrawerPaper = styled.div` width: ${props => props.width}px; height: 100%; position: relative; transition: width 0.2s ease; `; // 拖拽调整条样式 const Resizer = styled.div` position: absolute; top: 0; right: 0; width: 5px; height: 100%; cursor: col-resize; background-color: rgba(0, 0, 0, 0.1); &:hover { background-color: rgba(0, 0, 0, 0.3); } `; const CustomDrawer = ({ open, onClose, children, initialWidth = 300, minWidth = 200, maxWidth = 600 }) => { const [width, setWidth] = useState(initialWidth); const isResizing = useRef(false); const startX = useRef(0); const startWidth = useRef(0); const handleMouseDown = (e) => { isResizing.current = true; startX.current = e.clientX; startWidth.current = width; document.addEventListener('mousemove', handleMouseMove); document.addEventListener('mouseup', handleMouseUp); }; const handleMouseMove = (e) => { if (!isResizing.current) return; const deltaX = e.clientX - startX.current; const newWidth = startWidth.current + deltaX; if (newWidth >= minWidth && newWidth <= maxWidth) { setWidth(newWidth); } }; const handleMouseUp = () => { isResizing.current = false; document.removeEventListener('mousemove', handleMouseMove); document.removeEventListener('mouseup', handleMouseUp); }; useEffect(() => { return () => { // 组件卸载时清理事件监听 document.removeEventListener('mousemove', handleMouseMove); document.removeEventListener('mouseup', handleMouseUp); }; }, []); return ( <Drawer variant="persistent" anchor="left" open={open} onClose={onClose} > <DrawerPaper width={width}> {children} <Resizer onMouseDown={handleMouseDown} /> </DrawerPaper> </Drawer> ); }; export default CustomDrawer;
关键转换说明
- 替换
makeStyles为Emotionstyled:将原样式定义全部迁移到styled组件中,通过props传递动态值(如抽屉宽度),实现响应式样式变化。 - 保留MUI组件特性:直接基于MUI原生
Drawer扩展样式,保留原组件的所有props(如open、onClose)。 - 动态样式传递:抽屉宽度通过
DrawerPaper的widthprops实时传递,替代原makeStyles中的动态样式函数。 - 拖拽逻辑完整保留:原有的鼠标事件监听逻辑未做修改,确保调整大小的功能正常运行。
使用示例
import CustomDrawer from './CustomDrawer'; import { useState } from 'react'; function App() { const [drawerOpen, setDrawerOpen] = useState(true); return ( <div> <button onClick={() => setDrawerOpen(!drawerOpen)}>切换抽屉</button> <CustomDrawer open={drawerOpen} onClose={() => setDrawerOpen(false)} initialWidth={300} minWidth={200} maxWidth={600} > <div style={{ padding: '16px' }}> <h2>可调整大小的抽屉</h2> <p>拖动右侧边缘调整宽度</p> </div> </CustomDrawer> </div> ); } export default App;
内容的提问来源于stack exchange,提问作者Aaron
相关产品推荐
相关产品推荐

