React MUI
学习资源
- 官方文档:MUI 官网 (必看,文档质量极高)
- 组件库:MUI 组件 API (查阅所有组件的 props)
- 设计规范:Material Design (理解设计背后的思想)
1. 什么是 Material-UI (MUI)?
MUI 是一个实现了 Google Material Design 设计规范的 React UI 组件库。它提供了一系列高质量、开箱即用的 React 组件,让你能快速构建美观、现代且一致的用户界面。 核心优势:
- 🎨 设计系统:遵循 Material Design,保证了视觉和交互的一致性。
- 🧩 组件丰富:提供从基础按钮到复杂数据表格的全套组件。
- 🛠️ 高度可定制:主题系统让你可以轻松定制全局样式,打造品牌专属的 UI。
- 📱 开箱即用:组件默认支持响应式设计、无障碍访问(a11y)和暗黑模式。
- 🔧 开发体验好:与 React 生态完美融合,TypeScript 支持优秀。
2. 核心概念
2.1 Material Design
MUI 的基石。它是一套由 Google 推出的综合性设计语言,涵盖了视觉、动效、交互、布局等方方面面。使用 MUI,你就在实践这套设计规范。
2.2 主题
这是 MUI 的灵魂! 主题是一个 JavaScript 对象,包含了你应用的全局样式配置,如颜色、字体、间距、阴影等。
- 作用:实现“一处定义,处处生效”。你可以在主题中定义主色调,所有使用该颜色的组件都会自动更新。
- 核心:
createTheme函数和ThemeProvider组件。
2.3 组件与样式
MUI 组件的样式是其最强大的部分之一,理解它至关重要。
sxProp (推荐):一个超级属性,用于快速、简洁地应用任何 CSS 样式或主题相关的值。它解决了 95% 的样式定制需求。styledAPI:当你需要创建一个可复用的、带自定义样式的组件时使用。这是最强大的样式解决方案。
3. 快速上手
3.1 安装
# 使用 npm
npm install @mui/material @emotion/react @emotion/styled
# 使用 yarn
yarn add @mui/material @emotion/react @emotion/styled
# (可选) 安装图标库
npm install @mui/icons-material
注意:MUI v5 依赖 emotion 作为其默认的样式引擎。
3.2 基本用法
import React from 'react';
import Button from '@mui/material/Button';
import Typography from '@mui/material/Typography';
function App() {
return (
<div>
<Typography variant="h4">欢迎使用 MUI</Typography>
<Button variant="contained" color="primary">
点击我
</Button>
</div>
);
}
4. 核心组件与布局
4.1 布局组件
Container:内容居中的容器,提供响应式的max-width。Grid:最重要的布局组件。基于 12 列的弹性网格系统,用于创建复杂的响应式布局。import Grid from '@mui/material/Grid'; <Grid container spacing={2}> <Grid item xs={12} sm={6} md={4}> <div>项目 1</div> </Grid> <Grid item xs={12} sm={6} md={4}> <div>项目 2</div> </Grid> </Grid>Stack:用于管理一维布局(水平或垂直),替代传统的 flexbox 写法,非常方便。import Stack from '@mui/material/Stack'; <Stack direction="row" spacing={2}> <Button>按钮1</Button> <Button>按钮2</Button> </Stack>
4.2 常用组件
布局与容器
Container:容器组件,用于将内容居中并限制其最大宽度,适配不同的屏幕尺寸。Stack:栈式布局组件,用于控制子元素的间距,简化了 flexbox 的使用。Grid:网格布局组件,基于 12 列的栅格系统,用于构建复杂的二维响应式布局。Paper:纸质材质容器,用于在白色背景上显示内容,通常带有阴影。
表单与输入
TextField:多功能文本输入框,集成了 Input、Label 和辅助文本,支持多种样式。Button:按钮,有多种 variant (text, outlined, contained) 和 color。Checkbox&Radio:复选框和单选按钮,用于从一组选项中进行选择。Select:下拉选择菜单,用于从列表中选择一个选项。Switch:开关控件,用于开启或关闭某个状态。Slider:滑块组件,用于在一个范围内选择数值。Autocomplete:自动完成输入框,提供输入建议或搜索过滤功能。FormControl&FormGroup:表单控件容器,用于统一管理表单元素的状态和布局。
反馈与提示
Alert:警告提示框,用于向用户展示重要信息,支持不同严重级别。Snackbar:轻量级消息提示,通常出现在屏幕底部,用于显示非阻塞的操作反馈。Backdrop:背景遮罩,通常用于加载状态,模糊背景并聚焦用户注意力。CircularProgress/LinearProgress:环形或线性进度指示器,展示数据加载或处理进度。Tooltip:工具提示,鼠标悬停时显示的补充信息文本。
导航
Tabs:选项卡切换,用于在同一层级内容之间快速切换。BottomNavigation:底部导航栏,常用于移动端,在少数几个顶级视图之间切换。Breadcrumbs:面包屑导航,用于显示用户在网站层级结构中的当前位置。Menu:菜单列表,通常点击触发,展示一组操作或链接。Pagination:分页组件,用于将数据或内容分页显示。Link:链接组件,对原生<a>标签的样式封装。
数据展示
Table:数据表格,用于展示结构化数据,常配合 TableHead、TableRow、TableCell 使用。List&ListItem:列表容器和列表项,用于展示连续的文本或图标内容。Avatar:头像组件,用于展示用户头像、图标或文字。Chip:标签/纸片组件,用于展示输入实体、属性或小型操作(如删除标签)。Divider:分割线,用于视觉上分隔内容区域。Badge:徽标,用于在图标或文字右上角显示通知数量或状态(如小红点)。ImageList:图像列表,用于以网格形式展示一组图片集合。
基础与核心
Box:最灵活的组件。它本质上是一个<div>,但可以直接使用sxprop,是处理布局和样式的“瑞士军刀”。Typography:用于规范化文本样式,通过variant属性应用不同的字体大小和权重。Icon&SvgIcon:图标组件,用于渲染图标路径或使用 Material Icons 字体库。CssBaseline:样式重置组件,用于在不同浏览器间保持一致的样式基线(如 box-sizing、字体)。
表面与弹窗
AppBar&Toolbar:创建顶部应用栏。Drawer:侧边导航栏。Card:卡片容器,用于展示相关信息。Modal&Dialog:弹窗和对话框。
5. 样式定制(核心重点)
5.1 sx Prop:快速样式
sx prop 允许你直接在组件上写样式,并且能访问主题值。
import Box from '@mui/material/Box';
<Box
sx={{
backgroundColor: 'primary.main', // 使用主题中的颜色
color: 'white',
p: 2, // padding: 16px (MUI 的 spacing 单位)
m: 1, // margin: 8px
borderRadius: 1,
'&:hover': { // 伪类选择器
backgroundColor: 'primary.dark',
},
}}
>
这是一个使用 sx prop 的 Box
</Box>
为什么 sx 这么强?
- 直接访问主题:
primary.main、spacing(2)等。 - 简写属性:
pfor padding,mfor margin,pxfor padding-x。 - 响应式设计:可以传入对象实现断点响应。
sx={{ fontSize: { xs: '1rem', sm: '1.2rem', md: '1.5rem' } }}
5.2 主题定制:全局控制
这是打造品牌感的关键。 步骤 1:创建主题
// theme.js
import { createTheme } from '@mui/material/styles';
export const theme = createTheme({
palette: {
primary: {
main: '#1976d2', // 你的品牌主色
},
secondary: {
main: '#dc004e', // 你的品牌辅色
},
},
typography: {
fontFamily: 'Roboto, Arial, sans-serif',
h1: {
fontSize: '3rem',
},
},
});
步骤 2:在应用中提供主题
// App.js
import { ThemeProvider, CssBaseline } from '@mui/material';
import { theme } from './theme';
function App() {
return (
<ThemeProvider theme={theme}>
{/* CssBaseline 用于重置 CSS,提供一致的跨浏览器基础样式 */}
<CssBaseline />
{/* 你的应用内容 */}
<MyAppContent />
</ThemeProvider>
);
}
现在,所有组件都会使用你定义的主题了!
5.3 styled API:创建自定义组件
当你需要一个可复用的、深度定制的组件时,使用 styled。
import { Button } from '@mui/material';
import { styled } from '@mui/material/styles';
const CustomButton = styled(Button)(({ theme }) => ({
backgroundColor: theme.palette.success.main,
color: 'white',
padding: theme.spacing(2, 4),
'&:hover': {
backgroundColor: theme.palette.success.dark,
},
}));
// 使用
<CustomButton>自定义按钮</CustomButton>
6. 进阶技巧
6.1 暗黑模式
MUI 对暗黑模式提供了极好的支持。
// theme.js
import { createTheme } from '@mui/material/styles';
export const lightTheme = createTheme({ /* ... */ });
export const darkTheme = createTheme({
palette: {
mode: 'dark', // 只需设置这一项!
// 其他配置...
},
});
然后你可以在应用中动态切换 ThemeProvider 的 theme 属性。
6.2 自定义 Breakpoints(断点)
你可以在主题中自定义响应式断点,以适应你的设计需求。
// theme.js
export const theme = createTheme({
breakpoints: {
values: {
xs: 0,
sm: 600,
md: 900,
lg: 1200,
xl: 1536,
},
},
});
7. 最佳实践与常见问题
- 优先使用
sxprop:对于一次性、局部的样式调整,sx是最快最简洁的选择。 - 逻辑与样式分离:用
styledAPI 创建可复用的 UI 组件,把样式逻辑从业务组件中抽离出来。 - 拥抱
Box和Stack:它们能极大简化你的布局代码,减少手写 CSS。 - 利用主题:不要硬编码颜色和间距。将它们定义在主题中,方便维护和全局修改。
- 性能:
sxprop 的性能非常高,但避免在渲染循环中动态创建复杂的sx对象。如果样式是静态的,可以将其提取到组件外部。