使用 UI 庫能節省大量視覺設計和操作流程的前置設定,縮短開發時間,更重要的是在後續維護中也仍能保持一致性。想想不用自己刻頁碼省略邏輯,做 OTP 也會自動焦點下一個欄位,是不是很開心?😉
這是【套件筆記】開出的新系列 React UI 庫,我想針對幾項常見的 UI 庫做介紹與比較。結尾也會附上 Page 讓大家感受在電腦網頁與手機操作的差異。
範例版本
- React 19.1.1
- Vite 7.1
- MUI core 7.3
- MUI X 6
MUI 介紹
MUI(原名 Material UI)是一個 React UI 元件庫。由前 Google 工程師 Olivier Tassinari 於 2014 年創立,目前是獨立公司 MUI Inc. 維護。最初以 Google Material Design 規範為基礎,所以我們會看到它的風格和 Google 有一定相似,因為避免混淆才改名為 MUI。
MUI 有多個子產品,每個子產品在客製樣式主題上有不同辦法,這是我覺得它是初學者很容易搞不懂的地方,需要多花點時間適應:
- MUI Core (原 Material UI)
最核心的 UI 元件庫,依循 Google Material Design 規範,提供 Button、Dialog、Table、Grid 等常用元件。 - Joy UI
不受限於 Material Design,適合需要自訂品牌風格的專案。但 MUI 網站上寫道:”Joy UI is in beta and development is currently on hold. When starting a new project from scratch, we recommend Material UI over Joy UI because we can guarantee ongoing support.” - MUI Base
提供「無樣式」的低階元件,適合需要完全客製化樣式,但又想重用互動邏輯的團隊。現在已經被 Base UI 取代。 - MUI X
進階元件,部分需付費(例如複數篩選表格)。包含 DataGrid(資料表格)、Date/Time Pickers(日期時間選擇器)等。 - MUI System
樣式系統(theme、spacing、typography、styled API),幫助一致化設計與快速開發。
如果你是設計師,推薦直接看看這些 Template。選定幾個主題定調 Design Guideline。我做設計稿的時候也很喜歡來這裡翻寶庫找靈感 😚
安裝 Material UI
在你的 Vite 專案 terminal 輸入
1 | npm install @mui/material @emotion/react @emotion/styled |
MUI 匯入元件
1 | import Button from '@mui/material/Button' // Tree Shaking 最佳,體積較小,但一行行累積起來很會堆疊很高 |
為元件套用樣式與主題
指定元件套用樣式
使用
sx
語法糖。直接指定樣式名稱,下面範例的 label 在 hover 時會改變顏色。
1
2
3
4
5
6
7
8<Chip
sx={{
p:2, // theme.spacing(2) = 16px
'&:hover, & .MuiChip-label': {
color: 'theme.palette.text.primary',
},
}}
/>如果想重複使用上面的客製 Chip,可以改用 styled()。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17import { styled } from "@mui/material/styles";
import { Chip } from "@mui/material";
const CustomChip = styled(Chip)(({ theme }) => ({
padding: theme.spacing(2),
color: theme.palette.text.primary,
'&:hover, & .MuiChip-label': {
color: theme.palette.primary.main,
},
}));
export default function App() {
return <div>
<CustomChip label="Custom Chip 1" />
<CustomChip label="Custom Chip 2" />
</div>;
}
局部套用樣式
ThemeProvider
+createTheme
ThemeProvider
提供 theme context(主題)給全域或局部。覆蓋字級、色票、間距等設定。當作全域使用時,在內包裹的是<App />
即可。createTheme
可用於覆蓋主題設定,也能擴充新設定,之後在下一篇說明。
1
2
3
4
5
6
7
8
9
10import { ThemeProvider, createTheme } from "@mui/material/styles";
const theme = createTheme({
palette: { primary: { main: '#1976d2' } },
});
<ThemeProvider theme={theme}>
<Button color="primary">主題按鈕</Button>
</ThemeProvider>建立主題並全域套用
ThemeProvider
+GlobalStyles
+CssBaseline
+createTheme
CssBaseline
MUI 內建,提供一致的跨瀏覽器預設樣式,類似 reset.css 的作用。GlobalStyles
注入全域 CSS 規則,可額外自訂規則<GlobalStyles styles={{ body: { backgroundColor: '#fafafa' } }} />
。
1
2
3
4
5
6
7
8
9
10
11// main.tsx
import { CssBaseline, GlobalStyles, StyledEngineProvider, ThemeProvider } from "@mui/material";
import muitheme from './theme/muiTheme';
<StyledEngineProvider injectFirst >
<ThemeProvider theme={muitheme}>
<CssBaseline />
<GlobalStyles />
<App />
</ThemeProvider>
</StyledEngineProvider>
MUI icons
MUI 是基於實現 Material Design 的 library,如果想維持一致視覺,推薦可以直接使用 Google Fonts 透過 <link>
或 npm 安裝字型檔;MUI 也有提供包裝成 React Component 的版本,並且支援 TS IntelliSense(MUI icons 一覽)。
1 | // 安裝 |
另外你想使用 FontAwesome 或 React-Icons 也可以,React-Icons 本身就包含 Material Design Icons。
下一篇將介紹 MUI 如何客製樣式主題~