如何在Material UI v5中创建可导入主题并在Header组件中使用类样式
Material UI 5 组件样式抽离解决方案
代码问题分析
- 错误使用
useTheme()获取样式类:useTheme()返回的是MUI全局主题对象(包含调色板、断点、形状等配置),并非自定义的组件样式类,因此classes.toolbar这类调用无效。 - 组件自定义样式不应写在
createTheme中:createTheme用于配置全局主题规则,组件级自定义样式需通过makeStyles或styled实现。
步骤1:抽离组件样式为独立模块
创建src/styles/Header.styles.js文件,使用MUI5的makeStyles定义组件专属样式:
import { makeStyles, alpha } from '@mui/styles'; const useStyles = makeStyles((theme) => ({ title: { display: 'none', [theme.breakpoints.up('sm')]: { display: 'block', }, }, search: { position: 'relative', borderRadius: theme.shape.borderRadius, backgroundColor: alpha(theme.palette.common.white, 0.15), '&:hover': { backgroundColor: alpha(theme.palette.common.white, 0.25) }, marginRight: theme.spacing(2), marginLeft: 0, width: '100%', [theme.breakpoints.up('sm')]: { marginLeft: theme.spacing(3), width: 'auto' }, }, searchIcon: { padding: theme.spacing(0, 2), height: '100%', position: 'absolute', pointerEvents: 'none', display: 'flex', alignItems: 'center', justifyContent: 'center', }, inputRoot: { color: 'inherit', }, inputInput: { padding: theme.spacing(1, 1, 1, 0), paddingLeft: `calc(1em + ${theme.spacing(4)}px)`, transition: theme.transitions.create('width'), width: '100%', [theme.breakpoints.up('md')]: { width: '20ch' }, }, toolbar: { display: 'flex', justifyContent: 'space-between', }, })); export default useStyles;
步骤2:抽离全局主题(可选)
若需自定义全局主题(如调色板、断点),创建src/theme.js:
import { createTheme } from '@mui/material/styles'; const theme = createTheme({ palette: { primary: { main: '#1976d2', }, }, // 可添加其他全局主题配置 }); export default theme;
步骤3:重构Header组件
修改Header.js,导入抽离的样式和主题,正确使用样式类:
import React from 'react'; import { Autocomplete } from '@react-google-maps/api'; import { AppBar, Toolbar, Typography, InputBase, Box } from '@mui/material'; import SearchIcon from '@mui/icons-material/Search'; import { ThemeProvider } from '@mui/material/styles'; import useStyles from '../styles/Header.styles'; import theme from '../theme'; // 无需自定义主题可省略此导入及ThemeProvider const Header = () => { const classes = useStyles(); // 获取组件样式类 return ( <ThemeProvider theme={theme}> <AppBar position='static'> <Toolbar className={classes.toolbar}> <Typography variant='h5' className={classes.title}> Travel Advisor </Typography> <Box display='flex'> <Typography variant='h6' className={classes.title}> Explore new places </Typography> {/*<Autocomplete>*/} <div className={classes.search}> <div className={classes.searchIcon}> <SearchIcon /> </div> <InputBase placeholder="Search..." classes={{ root: classes.inputRoot, input: classes.inputInput }} /> </div> {/*</Autocomplete>*/} </Box> </Toolbar> </AppBar> </ThemeProvider> ); }; export default Header;
额外说明
- 使用
makeStyles需先安装依赖:npm install @mui/styles或yarn add @mui/styles - 若偏好MUI5推荐的
styled组件写法,可将样式改为组件形式,示例:
之后直接在组件中使用import { styled } from '@mui/material/styles'; import Toolbar from '@mui/material/Toolbar'; const StyledToolbar = styled(Toolbar)(({ theme }) => ({ display: 'flex', justifyContent: 'space-between', }));<StyledToolbar>替代<Toolbar className={classes.toolbar}>即可。
内容的提问来源于stack exchange,提问作者Maximo Juan Andres Mancilla Mi
相关产品推荐
相关产品推荐

