Material-UI 快速开始 #
创建第一个 MUI 应用 #
让我们从创建一个简单的登录页面开始,逐步了解 MUI 的核心概念。
完整示例 #
jsx
import {
Container,
Box,
TextField,
Button,
Typography,
Link,
Card,
CardContent,
} from '@mui/material';
function LoginPage() {
return (
<Container maxWidth="sm">
<Box sx={{ mt: 8 }}>
<Card>
<CardContent sx={{ p: 4 }}>
<Typography variant="h4" align="center" gutterBottom>
登录
</Typography>
<Box component="form" sx={{ mt: 2 }}>
<TextField
fullWidth
label="邮箱地址"
type="email"
margin="normal"
/>
<TextField
fullWidth
label="密码"
type="password"
margin="normal"
/>
<Button
type="submit"
fullWidth
variant="contained"
sx={{ mt: 3, mb: 2 }}
>
登录
</Button>
<Typography align="center">
<Link href="#">忘记密码?</Link>
</Typography>
</Box>
</CardContent>
</Card>
</Box>
</Container>
);
}
export default LoginPage;
核心概念 #
1. 组件导入 #
MUI 组件从 @mui/material 导入:
jsx
import {
Button,
TextField,
Container,
Box,
Typography,
} from '@mui/material';
2. ThemeProvider 和 CssBaseline #
ThemeProvider 提供主题上下文,CssBaseline 提供全局样式重置:
jsx
import { ThemeProvider, CssBaseline, createTheme } from '@mui/material';
const theme = createTheme();
function App() {
return (
<ThemeProvider theme={theme}>
<CssBaseline />
<LoginPage />
</ThemeProvider>
);
}
3. sx Prop #
sx prop 是 MUI 最强大的样式工具:
jsx
<Box
sx={{
p: 2,
m: 1,
bgcolor: 'primary.main',
color: 'white',
borderRadius: 1,
}}
>
sx prop 示例
</Box>
常用组件速览 #
布局组件 #
Container #
容器组件,用于限制内容宽度:
jsx
<Container maxWidth="sm">
小容器 (600px)
</Container>
<Container maxWidth="md">
中等容器 (900px)
</Container>
<Container maxWidth="lg">
大容器 (1200px)
</Container>
Box #
通用容器,类似 <div>:
jsx
<Box sx={{ p: 2, bgcolor: 'grey.100' }}>
这是一个 Box
</Box>
Stack #
堆叠布局,用于垂直或水平排列:
jsx
<Stack spacing={2} direction="column">
<Box>项目 1</Box>
<Box>项目 2</Box>
<Box>项目 3</Box>
</Stack>
<Stack spacing={2} direction="row">
<Box>项目 1</Box>
<Box>项目 2</Box>
<Box>项目 3</Box>
</Stack>
Grid #
网格布局系统:
jsx
<Grid container spacing={2}>
<Grid item xs={12} md={6}>
<Box sx={{ bgcolor: 'primary.light', p: 2 }}>左侧</Box>
</Grid>
<Grid item xs={12} md={6}>
<Box sx={{ bgcolor: 'secondary.light', p: 2 }}>右侧</Box>
</Grid>
</Grid>
输入组件 #
Button #
按钮组件:
jsx
<Stack spacing={2} direction="row">
<Button variant="text">Text</Button>
<Button variant="contained">Contained</Button>
<Button variant="outlined">Outlined</Button>
</Stack>
<Stack spacing={2} direction="row" sx={{ mt: 2 }}>
<Button color="primary">Primary</Button>
<Button color="secondary">Secondary</Button>
<Button color="error">Error</Button>
<Button color="success">Success</Button>
</Stack>
TextField #
文本输入框:
jsx
<Stack spacing={2}>
<TextField label="标准输入" variant="standard" />
<TextField label="填充输入" variant="filled" />
<TextField label="轮廓输入" variant="outlined" />
<TextField
label="带错误提示"
error
helperText="请输入有效内容"
/>
<TextField
label="禁用状态"
disabled
/>
</Stack>
Select #
选择器:
jsx
import { FormControl, InputLabel, Select, MenuItem } from '@mui/material';
function BasicSelect() {
const [age, setAge] = useState('');
return (
<FormControl fullWidth>
<InputLabel>年龄</InputLabel>
<Select
value={age}
label="年龄"
onChange={(e) => setAge(e.target.value)}
>
<MenuItem value={10}>10岁</MenuItem>
<MenuItem value={20}>20岁</MenuItem>
<MenuItem value={30}>30岁</MenuItem>
</Select>
</FormControl>
);
}
Checkbox 和 Radio #
jsx
import { FormControlLabel, Checkbox, Radio, RadioGroup } from '@mui/material';
<Stack spacing={2}>
<FormControlLabel control={<Checkbox />} label="同意条款" />
<RadioGroup defaultValue="male">
<FormControlLabel value="male" control={<Radio />} label="男" />
<FormControlLabel value="female" control={<Radio />} label="女" />
</RadioGroup>
</Stack>
数据展示组件 #
Typography #
文字排版:
jsx
<Stack spacing={1}>
<Typography variant="h1">H1 标题</Typography>
<Typography variant="h2">H2 标题</Typography>
<Typography variant="h3">H3 标题</Typography>
<Typography variant="h4">H4 标题</Typography>
<Typography variant="h5">H5 标题</Typography>
<Typography variant="h6">H6 标题</Typography>
<Typography variant="subtitle1">副标题 1</Typography>
<Typography variant="subtitle2">副标题 2</Typography>
<Typography variant="body1">正文 1</Typography>
<Typography variant="body2">正文 2</Typography>
<Typography variant="caption">说明文字</Typography>
</Stack>
Card #
卡片组件:
jsx
<Card sx={{ maxWidth: 345 }}>
<CardMedia
component="img"
height="140"
image="/static/images/cards/contemplative-reptile.jpg"
alt="green iguana"
/>
<CardContent>
<Typography gutterBottom variant="h5" component="div">
蜥蜴
</Typography>
<Typography variant="body2" color="text.secondary">
蜥蜴是一类广泛分布的爬行动物,全球有超过6000种。
</Typography>
</CardContent>
<CardActions>
<Button size="small">分享</Button>
<Button size="small">了解更多</Button>
</CardActions>
</Card>
Avatar #
头像组件:
jsx
<Stack direction="row" spacing={2}>
<Avatar>H</Avatar>
<Avatar sx={{ bgcolor: 'primary.main' }}>N</Avatar>
<Avatar sx={{ bgcolor: 'secondary.main' }}>OP</Avatar>
<Avatar alt="Remy Sharp" src="/static/images/avatar/1.jpg" />
</Stack>
反馈组件 #
Dialog #
对话框:
jsx
import { Dialog, DialogTitle, DialogContent, DialogActions } from '@mui/material';
function AlertDialog() {
const [open, setOpen] = useState(false);
return (
<>
<Button variant="outlined" onClick={() => setOpen(true)}>
打开对话框
</Button>
<Dialog open={open} onClose={() => setOpen(false)}>
<DialogTitle>确认操作</DialogTitle>
<DialogContent>
<Typography>你确定要执行此操作吗?</Typography>
</DialogContent>
<DialogActions>
<Button onClick={() => setOpen(false)}>取消</Button>
<Button onClick={() => setOpen(false)} autoFocus>
确认
</Button>
</DialogActions>
</Dialog>
</>
);
}
Snackbar #
消息提示:
jsx
import { Snackbar, Alert } from '@mui/material';
function SimpleSnackbar() {
const [open, setOpen] = useState(false);
return (
<>
<Button onClick={() => setOpen(true)}>显示消息</Button>
<Snackbar
open={open}
autoHideDuration={3000}
onClose={() => setOpen(false)}
>
<Alert severity="success">操作成功!</Alert>
</Snackbar>
</>
);
}
Progress #
进度指示器:
jsx
<Stack spacing={2} direction="row">
<CircularProgress />
<CircularProgress color="secondary" />
<CircularProgress variant="determinate" value={75} />
</Stack>
<Stack spacing={2} sx={{ mt: 2 }}>
<LinearProgress />
<LinearProgress color="secondary" />
<LinearProgress variant="determinate" value={50} />
</Stack>
实战示例:简单仪表板 #
jsx
import {
AppBar,
Toolbar,
Typography,
Drawer,
List,
ListItem,
ListItemIcon,
ListItemText,
Container,
Box,
Card,
CardContent,
Grid,
IconButton,
} from '@mui/material';
import {
Dashboard as DashboardIcon,
People as PeopleIcon,
Settings as SettingsIcon,
Menu as MenuIcon,
} from '@mui/icons-material';
const drawerWidth = 240;
function Dashboard() {
return (
<Box sx={{ display: 'flex' }}>
<AppBar position="fixed" sx={{ zIndex: 1201 }}>
<Toolbar>
<IconButton color="inherit" edge="start" sx={{ mr: 2 }}>
<MenuIcon />
</IconButton>
<Typography variant="h6" noWrap>
管理后台
</Typography>
</Toolbar>
</AppBar>
<Drawer
variant="permanent"
sx={{
width: drawerWidth,
flexShrink: 0,
'& .MuiDrawer-paper': { width: drawerWidth, boxSizing: 'border-box' },
}}
>
<Toolbar />
<List>
<ListItem button>
<ListItemIcon><DashboardIcon /></ListItemIcon>
<ListItemText primary="仪表板" />
</ListItem>
<ListItem button>
<ListItemIcon><PeopleIcon /></ListItemIcon>
<ListItemText primary="用户管理" />
</ListItem>
<ListItem button>
<ListItemIcon><SettingsIcon /></ListItemIcon>
<ListItemText primary="设置" />
</ListItem>
</List>
</Drawer>
<Box component="main" sx={{ flexGrow: 1, p: 3 }}>
<Toolbar />
<Container maxWidth="lg">
<Grid container spacing={3}>
<Grid item xs={12} md={4}>
<Card>
<CardContent>
<Typography color="textSecondary" gutterBottom>
总用户
</Typography>
<Typography variant="h4">1,234</Typography>
</CardContent>
</Card>
</Grid>
<Grid item xs={12} md={4}>
<Card>
<CardContent>
<Typography color="textSecondary" gutterBottom>
活跃用户
</Typography>
<Typography variant="h4">856</Typography>
</CardContent>
</Card>
</Grid>
<Grid item xs={12} md={4}>
<Card>
<CardContent>
<Typography color="textSecondary" gutterBottom>
新增用户
</Typography>
<Typography variant="h4">128</Typography>
</CardContent>
</Card>
</Grid>
</Grid>
</Container>
</Box>
</Box>
);
}
export default Dashboard;
下一步 #
现在你已经掌握了 MUI 的基础用法,继续学习 主题基础,深入了解如何定制你的应用主题!
最后更新:2026-03-28