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

如何在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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 17:16:07