react Material UI 基本组件

34 阅读7分钟

React MUI

学习资源

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 组件的样式是其最强大的部分之一,理解它至关重要。

  • sx Prop (推荐):一个超级属性,用于快速、简洁地应用任何 CSS 样式或主题相关的值。它解决了 95% 的样式定制需求。
  • styled API:当你需要创建一个可复用的、带自定义样式的组件时使用。这是最强大的样式解决方案。

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>,但可以直接使用 sx prop,是处理布局和样式的“瑞士军刀”。
  • 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.mainspacing(2) 等。
  • 简写属性p for padding, m for margin, px for 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', // 只需设置这一项!
    // 其他配置...
  },
});

然后你可以在应用中动态切换 ThemeProvidertheme 属性。

6.2 自定义 Breakpoints(断点)

你可以在主题中自定义响应式断点,以适应你的设计需求。

// theme.js
export const theme = createTheme({
  breakpoints: {
    values: {
      xs: 0,
      sm: 600,
      md: 900,
      lg: 1200,
      xl: 1536,
    },
  },
});

7. 最佳实践与常见问题

  1. 优先使用 sx prop:对于一次性、局部的样式调整,sx 是最快最简洁的选择。
  2. 逻辑与样式分离:用 styled API 创建可复用的 UI 组件,把样式逻辑从业务组件中抽离出来。
  3. 拥抱 BoxStack:它们能极大简化你的布局代码,减少手写 CSS。
  4. 利用主题:不要硬编码颜色和间距。将它们定义在主题中,方便维护和全局修改。
  5. 性能sx prop 的性能非常高,但避免在渲染循环中动态创建复杂的 sx 对象。如果样式是静态的,可以将其提取到组件外部。