Material-UI 图标系统 #

概述 #

MUI 提供了完整的图标解决方案,包括官方的 Material Icons 和自定义图标支持。

text
图标系统
│
├── @mui/icons-material  Material Icons(2000+)
├── SvgIcon               SVG 图标组件
├── Icon                  Font 图标组件
└── 自定义图标            自定义 SVG 图标

Material Icons #

安装 #

bash
npm install @mui/icons-material

基础用法 #

jsx
import { Delete, Add, Home, Settings } from '@mui/icons-material';

<Delete />
<Add />
<Home />
<Settings />

图标颜色 #

jsx
import { pink, green } from '@mui/material/colors';

<Stack direction="row" spacing={2}>
  <Delete color="primary" />
  <Delete color="secondary" />
  <Delete color="error" />
  <Delete color="warning" />
  <Delete color="success" />
  <Delete color="info" />
  <Delete sx={{ color: pink[500] }} />
  <Delete sx={{ color: green[500] }} />
</Stack>

图标尺寸 #

jsx
<Stack direction="row" spacing={2} alignItems="center">
  <Delete fontSize="small" />
  <Delete fontSize="medium" />
  <Delete fontSize="large" />
  <Delete sx={{ fontSize: 40 }} />
</Stack>

配合按钮使用 #

jsx
import { Button, IconButton } from '@mui/material';
import { Delete as DeleteIcon, Send as SendIcon, Add as AddIcon } from '@mui/icons-material';

<Stack spacing={2} direction="row">
  <Button variant="contained" startIcon={<AddIcon />}>
    添加
  </Button>
  <Button variant="contained" endIcon={<SendIcon />}>
    发送
  </Button>
  <IconButton aria-label="delete">
    <DeleteIcon />
  </IconButton>
</Stack>

配合输入框使用 #

jsx
import { TextField, InputAdornment } from '@mui/material';
import { AccountCircle, Lock, Search } from '@mui/icons-material';

<Stack spacing={2}>
  <TextField
    label="搜索"
    InputProps={{
      startAdornment: (
        <InputAdornment position="start">
          <Search />
        </InputAdornment>
      ),
    }}
  />
  <TextField
    label="用户名"
    InputProps={{
      startAdornment: (
        <InputAdornment position="start">
          <AccountCircle />
        </InputAdornment>
      ),
    }}
  />
  <TextField
    label="密码"
    type="password"
    InputProps={{
      endAdornment: (
        <InputAdornment position="end">
          <Lock />
        </InputAdornment>
      ),
    }}
  />
</Stack>

SvgIcon 组件 #

SvgIcon 是所有图标的基础组件,可以用于包装自定义 SVG。

基础用法 #

jsx
import { SvgIcon } from '@mui/material';

function HomeIcon(props) {
  return (
    <SvgIcon {...props}>
      <path d="M10 20v-6h4v6h5v-8h3L12 3 2 12h3v8z" />
    </SvgIcon>
  );
}

<HomeIcon />
<HomeIcon color="primary" />
<HomeIcon color="secondary" />

使用 SVG 路径 #

jsx
const path = 'M10 20v-6h4v6h5v-8h3L12 3 2 12h3v8z';

<SvgIcon>
  <path d={path} />
</SvgIcon>

从 SVG 文件导入 #

jsx
import { ReactComponent as Logo } from './logo.svg';

<SvgIcon component={Logo} viewBox="0 0 24 24" />

自定义图标 #

创建图标组件 #

jsx
import { SvgIcon } from '@mui/material';

export function CustomIcon(props) {
  return (
    <SvgIcon {...props}>
      <circle cx="12" cy="12" r="10" />
      <path d="M8 12l2 2 4-4" stroke="white" strokeWidth="2" fill="none" />
    </SvgIcon>
  );
}

使用 Lucide Icons #

jsx
import { SvgIcon } from '@mui/material';
import { Home, User, Settings } from 'lucide-react';

function LucideIcon({ icon: Icon, ...props }) {
  return (
    <SvgIcon component={Icon} {...props} />
  );
}

<LucideIcon icon={Home} />
<LucideIcon icon={User} />
<LucideIcon icon={Settings} />

使用 React Icons #

jsx
import { FaReact, FaVuejs, FaAngular } from 'react-icons/fa';
import { SvgIcon } from '@mui/material';

<SvgIcon component={FaReact} />
<SvgIcon component={FaVuejs} />
<SvgIcon component={FaAngular} />

Icon 组件(Font 图标) #

基础用法 #

jsx
import { Icon } from '@mui/material';

<Icon>star</Icon>
<Icon>favorite</Icon>
<Icon>settings</Icon>

配合 Material Icons 字体 #

jsx
<link
  rel="stylesheet"
  href="https://fonts.googleapis.com/css2?family=Material+Icons"
/>

<Icon>home</Icon>
<Icon color="primary">star</Icon>
<Icon fontSize="large">favorite</Icon>

不同图标字体 #

jsx
<link
  rel="stylesheet"
  href="https://fonts.googleapis.com/css2?family=Material+Icons+Outlined"
/>

<Icon baseClassName="material-icons-outlined">star</Icon>

图标库分类 #

常用图标 #

类别 图标示例
导航 Home, Menu, ArrowBack, ArrowForward
操作 Add, Edit, Delete, Save, Cancel
通信 Mail, Phone, Chat, Send
文件 Folder, File, Download, Upload
媒体 Play, Pause, VolumeUp, VolumeOff
社交 Share, Favorite, ThumbUp, Comment
状态 Check, Close, Warning, Error

搜索图标 #

jsx
import { Search as SearchIcon } from '@mui/icons-material';

<TextField
  placeholder="搜索图标..."
  InputProps={{
    startAdornment: <SearchIcon />,
  }}
/>

图标最佳实践 #

语义化使用 #

jsx
<IconButton aria-label="删除项目">
  <DeleteIcon />
</IconButton>

<Button startIcon={<AddIcon />}>添加项目</Button>

一致的尺寸 #

jsx
const iconSize = {
  small: 20,
  medium: 24,
  large: 32,
};

<DeleteIcon sx={{ fontSize: iconSize.small }} />
<DeleteIcon sx={{ fontSize: iconSize.medium }} />
<DeleteIcon sx={{ fontSize: iconSize.large }} />

图标按钮组 #

jsx
<IconButtonGroup>
  <IconButton aria-label="加粗">
    <FormatBoldIcon />
  </IconButton>
  <IconButton aria-label="斜体">
    <FormatItalicIcon />
  </IconButton>
  <IconButton aria-label="下划线">
    <FormatUnderlinedIcon />
  </IconButton>
</IconButtonGroup>

图标列表 #

jsx
<List>
  <ListItem>
    <ListItemIcon>
      <HomeIcon />
    </ListItemIcon>
    <ListItemText primary="首页" />
  </ListItem>
  <ListItem>
    <ListItemIcon>
      <SettingsIcon />
    </ListItemIcon>
    <ListItemText primary="设置" />
  </ListItem>
  <ListItem>
    <ListItemIcon>
      <LogoutIcon />
    </ListItemIcon>
    <ListItemText primary="退出" />
  </ListItem>
</List>

图标动画 #

旋转动画 #

jsx
<RefreshIcon
  sx={{
    animation: 'spin 1s linear infinite',
    '@keyframes spin': {
      '0%': { transform: 'rotate(0deg)' },
      '100%': { transform: 'rotate(360deg)' },
    },
  }}
/>

脉冲动画 #

jsx
<FavoriteIcon
  sx={{
    animation: 'pulse 1s ease-in-out infinite',
    '@keyframes pulse': {
      '0%': { transform: 'scale(1)' },
      '50%': { transform: 'scale(1.2)' },
      '100%': { transform: 'scale(1)' },
    },
  }}
/>

过渡动画 #

jsx
<IconButton
  sx={{
    '&:hover svg': {
      transform: 'rotate(90deg)',
    },
    '& svg': {
      transition: 'transform 0.3s',
    },
  }}
>
  <SettingsIcon />
</IconButton>

实战示例:图标选择器 #

jsx
import { useState } from 'react';
import {
  Grid,
  Paper,
  IconButton,
  TextField,
  InputAdornment,
  Typography,
} from '@mui/material';
import * as Icons from '@mui/icons-material';

function IconPicker({ value, onChange }) {
  const [search, setSearch] = useState('');
  const iconNames = Object.keys(Icons).filter(
    (name) => name.toLowerCase().includes(search.toLowerCase())
  );

  return (
    <Paper sx={{ p: 2, maxWidth: 400 }}>
      <TextField
        fullWidth
        placeholder="搜索图标..."
        value={search}
        onChange={(e) => setSearch(e.target.value)}
        InputProps={{
          startAdornment: (
            <InputAdornment position="start">
              <Icons.Search />
            </InputAdornment>
          ),
        }}
        sx={{ mb: 2 }}
      />
      <Grid container spacing={1} sx={{ maxHeight: 300, overflow: 'auto' }}>
        {iconNames.slice(0, 100).map((name) => {
          const Icon = Icons[name];
          return (
            <Grid item key={name}>
              <IconButton
                onClick={() => onChange(name)}
                color={value === name ? 'primary' : 'default'}
              >
                <Icon />
              </IconButton>
            </Grid>
          );
        })}
      </Grid>
    </Paper>
  );
}

下一步 #

继续学习 自定义组件,了解如何创建可复用的自定义组件!

最后更新:2026-03-28