- การใช้งาน MUI กับ Laravel 13 + React + Inertia
- Architecture
- 1. สร้าง Laravel Project
- 2. ติดตั้ง Material UI
- 3. สร้าง MUI Theme
- 4. ใช้ ThemeProvider
- 5. ทดลองสร้างหน้า MUI
- 6. ส่งข้อมูลจาก Laravel ไป React
- 7. แสดงข้อมูลด้วย MUI Table
- 8. สร้าง Form ด้วย MUI + Inertia
- 9. ใช้ MUI Icons
- 10. สร้าง Dashboard Layout
- 11. ใช้ MUI Dialog
- 12. ใช้ Snackbar
- 13. ใช้ MUI Data Grid
- 14. Laravel Pagination + MUI
- 15. Dark Mode
- 16. MUI กับ Tailwind ใช้พร้อมกันได้หรือไม่
- 17. MUI กับ shadcn/ui
- 18. โครงสร้าง Project ที่แนะนำ
- 19. Best Practices
- 20. Production Build
- Laravel + MUI เหมาะกับระบบแบบใด
- สรุป
- คำสั่งที่ใช้บ่อย
- เอกสารอ้างอิง
#การใช้งาน MUI กับ Laravel 13 + React + Inertia
การพัฒนา Web Application ด้วย Laravel ไม่ได้จำกัดอยู่เฉพาะ Blade หรือ Tailwind CSS เท่านั้น หากต้องการสร้าง UI ที่มี Component พร้อมใช้งานจำนวนมาก เช่น Button, TextField, Dialog, Table, Snackbar หรือ Data Grid เราสามารถใช้ Material UI (MUI) ร่วมกับ React และ Inertia.js ได้อย่างมีประสิทธิภาพ
แนวทางที่เหมาะกับ Laravel 13 คือ
Laravel 13
↓
Inertia 3
↓
React 19 + TypeScript
↓
Material UI (MUI)
Laravel จะรับผิดชอบงานฝั่ง Backend เช่น Routing, Validation, Authentication, Authorization และ Database ส่วน React + MUI จะรับผิดชอบด้าน User Interface
#MUI คืออะไร
MUI (Material UI) เป็น React Component Library ที่พัฒนาตามแนวคิด Material Design โดยมี Component พร้อมใช้งานจำนวนมาก เช่น
- Button
- TextField
- Card
- AppBar
- Drawer
- Dialog
- Snackbar
- Alert
- Table
- Grid
- Tabs
- Data Grid
ตัวอย่าง
import Button from '@mui/material/Button';
export default function Example() {
return (
<Button variant="contained">
Save
</Button>
);
}
เนื่องจาก MUI เป็น React Component Library จึงไม่สามารถนำ Component ของ MUI ไปใช้ใน Blade Template โดยตรงได้
ดังนั้น Stack ที่เหมาะสมคือ
Laravel + Inertia + React + MUI
#Architecture
ภาพรวม Architecture
Browser
│
▼
React + MUI
│
▼
Inertia.js
│
▼
Laravel Route
│
▼
Controller
│
▼
Eloquent ORM
│
▼
Database
MUI ทำหน้าที่เป็น Presentation Layer
ส่วน Laravel ทำหน้าที่เกี่ยวกับ
Routing
Validation
Authentication
Authorization
Business Logic
Database
Queue
Cache
Notification
#1. สร้าง Laravel Project
ติดตั้ง Laravel Installer
composer global require laravel/installer
จากนั้นสร้าง Project
laravel new laravel-mui
เลือก React Starter Kit
เข้า Project
cd laravel-mui
ติดตั้ง Package
npm install
รัน Development Server
composer run dev
หรือแยกรัน
php artisan serve
และ
npm run dev
#2. ติดตั้ง Material UI
ติดตั้ง MUI
npm install @mui/material @emotion/react @emotion/styled
ติดตั้ง Material Icons
npm install @mui/icons-material
หากต้องการใช้ Roboto Font
npm install @fontsource/roboto
#3. สร้าง MUI Theme
สร้างไฟล์
resources/js/theme.ts
ตัวอย่าง
import { createTheme } from '@mui/material/styles';
const theme = createTheme({
palette: {
primary: {
main: '#1976d2',
},
secondary: {
main: '#9c27b0',
},
},
typography: {
fontFamily: 'Roboto, sans-serif',
},
shape: {
borderRadius: 10,
},
});
export default theme;
ข้อดีของ Theme คือสามารถกำหนด Design System ของระบบจากจุดเดียว เช่น
- Primary Color
- Secondary Color
- Typography
- Border Radius
- Component Style
- Dark Mode
#4. ใช้ ThemeProvider
แก้ไขไฟล์
resources/js/app.tsx
เพิ่ม
import {
CssBaseline,
ThemeProvider
} from '@mui/material';
import theme from './theme';
ครอบ React Application
<ThemeProvider theme={theme}>
<CssBaseline />
{app}
</ThemeProvider>
CssBaseline จะช่วย Reset CSS และทำให้ Styling ของ MUI สอดคล้องกันทั้งระบบ
#5. ทดลองสร้างหน้า MUI
สร้างไฟล์
resources/js/pages/mui-demo.tsx
import {
Alert,
Box,
Button,
Card,
CardContent,
Container,
Stack,
Typography,
} from '@mui/material';
export default function MuiDemo() {
return (
<Container maxWidth="md" sx={{ py: 5 }}>
<Stack spacing={3}>
<Typography variant="h3">
Laravel + MUI
</Typography>
<Alert severity="success">
MUI ทำงานร่วมกับ Laravel ได้แล้ว
</Alert>
<Card>
<CardContent>
<Typography
variant="h5"
gutterBottom
>
Material UI
</Typography>
<Typography color="text.secondary">
หน้านี้ถูก Render ด้วย React และ MUI
</Typography>
<Box sx={{ mt: 3 }}>
<Button variant="contained">
Get Started
</Button>
</Box>
</CardContent>
</Card>
</Stack>
</Container>
);
}
สร้าง Route
use Illuminate\Support\Facades\Route;
use Inertia\Inertia;
Route::get('/mui-demo', function () {
return Inertia::render('mui-demo');
});
เปิด Browser
http://localhost:8000/mui-demo
#6. ส่งข้อมูลจาก Laravel ไป React
สมมติว่ามี Product
สร้าง Model
php artisan make:model Product -mcr
Controller
namespace App\Http\Controllers;
use App\Models\Product;
use Inertia\Inertia;
use Inertia\Response;
class ProductController extends Controller
{
public function index(): Response
{
return Inertia::render('products/index', [
'products' => Product::query()
->latest()
->get([
'id',
'name',
'price',
]),
]);
}
}
Route
use App\Http\Controllers\ProductController;
Route::get(
'/products',
[ProductController::class, 'index']
)->name('products.index');
ข้อมูลจะถูกส่งไปเป็น Props ของ React Component
#7. แสดงข้อมูลด้วย MUI Table
สร้าง
resources/js/pages/products/index.tsx
import {
Container,
Paper,
Table,
TableBody,
TableCell,
TableContainer,
TableHead,
TableRow,
Typography,
} from '@mui/material';
interface Product {
id: number;
name: string;
price: number;
}
interface Props {
products: Product[];
}
export default function ProductIndex({
products
}: Props) {
return (
<Container
maxWidth="lg"
sx={{ py: 4 }}
>
<Typography
variant="h4"
sx={{ mb: 3 }}
>
Products
</Typography>
<TableContainer component={Paper}>
<Table>
<TableHead>
<TableRow>
<TableCell>ID</TableCell>
<TableCell>Name</TableCell>
<TableCell align="right">
Price
</TableCell>
</TableRow>
</TableHead>
<TableBody>
{products.map((product) => (
<TableRow key={product.id}>
<TableCell>
{product.id}
</TableCell>
<TableCell>
{product.name}
</TableCell>
<TableCell align="right">
{product.price.toLocaleString()}
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</TableContainer>
</Container>
);
}
ข้อดีคือ React ไม่จำเป็นต้องเรียก REST API เพิ่ม เพราะข้อมูลถูกส่งจาก Laravel ผ่าน Inertia
#8. สร้าง Form ด้วย MUI + Inertia
สร้างหน้า
resources/js/pages/products/create.tsx
import { useForm } from '@inertiajs/react';
import {
Alert,
Button,
Container,
Stack,
TextField,
Typography,
} from '@mui/material';
import type { FormEvent } from 'react';
export default function ProductCreate() {
const form = useForm({
name: '',
price: '',
});
const submit = (
event: FormEvent
) => {
event.preventDefault();
form.post('/products');
};
return (
<Container
maxWidth="sm"
sx={{ py: 4 }}
>
<Typography
variant="h4"
sx={{ mb: 3 }}
>
Create Product
</Typography>
<Stack
component="form"
spacing={3}
onSubmit={submit}
>
{form.hasErrors && (
<Alert severity="error">
กรุณาตรวจสอบข้อมูลอีกครั้ง
</Alert>
)}
<TextField
label="Product Name"
value={form.data.name}
onChange={(event) =>
form.setData(
'name',
event.target.value
)
}
error={
Boolean(
form.errors.name
)
}
helperText={
form.errors.name
}
fullWidth
/>
<TextField
label="Price"
type="number"
value={form.data.price}
onChange={(event) =>
form.setData(
'price',
event.target.value
)
}
error={
Boolean(
form.errors.price
)
}
helperText={
form.errors.price
}
fullWidth
/>
<Button
type="submit"
variant="contained"
disabled={form.processing}
>
{form.processing
? 'Saving...'
: 'Save'
}
</Button>
</Stack>
</Container>
);
}
Laravel Validation
$data = $request->validate([
'name' => [
'required',
'string',
'max:255'
],
'price' => [
'required',
'numeric',
'min:0'
],
]);
เมื่อ Validation Error เกิดขึ้น Inertia จะส่ง Error กลับมายัง React
จากนั้น MUI สามารถแสดงผลด้วย
<TextField
error={Boolean(form.errors.name)}
helperText={form.errors.name}
/>
#9. ใช้ MUI Icons
ติดตั้ง
npm install @mui/icons-material
ตัวอย่าง
import AddIcon from '@mui/icons-material/Add';
import Button from '@mui/material/Button';
<Button
variant="contained"
startIcon={<AddIcon />}
>
Add Product
</Button>
#10. สร้าง Dashboard Layout
MUI มี Component ที่เหมาะสำหรับ Dashboard เช่น
AppBar
Drawer
Toolbar
Grid
Card
List
Table
Data Grid
ตัวอย่าง
import {
Card,
CardContent,
Grid,
Typography,
} from '@mui/material';
export default function Dashboard() {
return (
<Grid
container
spacing={3}
>
<Grid size={{
xs: 12,
md: 4
}}>
<Card>
<CardContent>
<Typography
color="text.secondary"
>
Users
</Typography>
<Typography variant="h4">
1,250
</Typography>
</CardContent>
</Card>
</Grid>
<Grid size={{
xs: 12,
md: 4
}}>
<Card>
<CardContent>
<Typography
color="text.secondary"
>
Orders
</Typography>
<Typography variant="h4">
380
</Typography>
</CardContent>
</Card>
</Grid>
<Grid size={{
xs: 12,
md: 4
}}>
<Card>
<CardContent>
<Typography
color="text.secondary"
>
Revenue
</Typography>
<Typography variant="h4">
฿245,000
</Typography>
</CardContent>
</Card>
</Grid>
</Grid>
);
}
#11. ใช้ MUI Dialog
ตัวอย่าง Confirmation Dialog
import {
Button,
Dialog,
DialogActions,
DialogContent,
DialogTitle,
} from '@mui/material';
import { useState } from 'react';
export default function DeleteDialog() {
const [open, setOpen] = useState(false);
return (
<>
<Button
color="error"
onClick={() =>
setOpen(true)
}
>
Delete
</Button>
<Dialog
open={open}
onClose={() =>
setOpen(false)
}
>
<DialogTitle>
Delete Product
</DialogTitle>
<DialogContent>
Are you sure you want to delete this product?
</DialogContent>
<DialogActions>
<Button
onClick={() =>
setOpen(false)
}
>
Cancel
</Button>
<Button
color="error"
variant="contained"
>
Delete
</Button>
</DialogActions>
</Dialog>
</>
);
}
#12. ใช้ Snackbar
Snackbar เหมาะสำหรับแสดง Notification
import {
Alert,
Snackbar,
} from '@mui/material';
import { useState } from 'react';
export default function Notification() {
const [open, setOpen] = useState(true);
return (
<Snackbar
open={open}
autoHideDuration={3000}
onClose={() =>
setOpen(false)
}
>
<Alert
severity="success"
variant="filled"
>
บันทึกข้อมูลเรียบร้อย
</Alert>
</Snackbar>
);
}
สามารถนำ Laravel Flash Session มาเชื่อมกับ Snackbar ได้
#13. ใช้ MUI Data Grid
สำหรับระบบที่มีข้อมูลจำนวนมากสามารถใช้ MUI X Data Grid
ติดตั้ง
npm install @mui/x-data-grid
ตัวอย่าง
import {
DataGrid
} from '@mui/x-data-grid';
const columns = [
{
field: 'id',
headerName: 'ID',
width: 90,
},
{
field: 'name',
headerName: 'Name',
flex: 1,
},
{
field: 'price',
headerName: 'Price',
width: 150,
},
];
export default function ProductTable({
products
}) {
return (
<DataGrid
rows={products}
columns={columns}
initialState={{
pagination: {
paginationModel: {
pageSize: 10,
},
},
}}
pageSizeOptions={[
10,
25,
50
]}
/>
);
}
เหมาะกับ
- Admin Panel
- Inventory
- Report
- User Management
- Audit Log
#14. Laravel Pagination + MUI
หากข้อมูลมีจำนวนมากไม่ควรโหลดทั้งหมดจาก Database
ใช้ Laravel Pagination
return Inertia::render(
'products/index',
[
'products' =>
Product::query()
->latest()
->paginate(10),
]
);
ข้อมูลที่ได้จะมีโครงสร้างประมาณ
products.data
products.current_page
products.last_page
products.total
จากนั้นสามารถนำไปใช้กับ
MUI Pagination
MUI TablePagination
MUI Data Grid
#15. Dark Mode
MUI รองรับ Dark Mode
import {
createTheme
} from '@mui/material/styles';
export function createAppTheme(
mode: 'light' | 'dark'
) {
return createTheme({
palette: {
mode,
primary: {
main: '#1976d2',
},
},
});
}
จากนั้นควบคุม Mode ด้วย React State
Light
Dark
System
#16. MUI กับ Tailwind ใช้พร้อมกันได้หรือไม่
สามารถใช้ร่วมกันได้
ตัวอย่าง
<Box className="p-4">
<Button variant="contained">
Save
</Button>
</Box>
แต่ควรกำหนดแนวทางให้ชัดเจน เช่น
MUI Theme
↓
Design Token
MUI sx
↓
Component Styling
Tailwind
↓
Utility / Layout บางส่วน
ไม่ควรกำหนด Style เดียวกันซ้ำทั้ง
sx
className
CSS
เพราะจะทำให้ Maintenance ยากขึ้น
#17. MUI กับ shadcn/ui
Laravel React Starter Kit อาจมี shadcn/ui อยู่แล้ว
เราสามารถติดตั้ง MUI เพิ่มได้
แนวทางที่แนะนำ
Laravel React Starter Kit
↓
ติดตั้ง MUI
↓
ใช้ MUI กับหน้าใหม่
↓
ค่อย ๆ เปลี่ยน Component
↓
ลด Component ที่ไม่จำเป็น
ไม่จำเป็นต้องลบ shadcn/ui และ Tailwind ออกทันที
#18. โครงสร้าง Project ที่แนะนำ
laravel-mui
│
├── app
│ ├── Http
│ │ └── Controllers
│ │ └── ProductController.php
│ │
│ └── Models
│ └── Product.php
│
├── resources
│ ├── js
│ │
│ ├── components
│ │ ├── Navbar.tsx
│ │ ├── ConfirmDialog.tsx
│ │ └── ProductForm.tsx
│ │
│ ├── layouts
│ │ └── MuiLayout.tsx
│ │
│ ├── pages
│ │ ├── dashboard.tsx
│ │ └── products
│ │ ├── index.tsx
│ │ ├── create.tsx
│ │ └── edit.tsx
│ │
│ ├── app.tsx
│ └── theme.ts
│
└── routes
└── web.php
#19. Best Practices
#ใช้ Laravel จัดการ Business Logic
Business Logic ควรอยู่ใน
Controller
Service
Action
Model
Policy
Form Request
ไม่ควรนำ Logic สำคัญไปไว้ใน React Component
#ใช้ Laravel Validation
ตัวอย่าง
$request->validate([
'name' => ['required'],
]);
จากนั้นแสดง Error ด้วย MUI
<TextField
error={
Boolean(errors.name)
}
helperText={
errors.name
}
/>
#สร้าง Reusable Components
ตัวอย่าง
components
├── ConfirmDialog.tsx
├── DataTable.tsx
├── FormTextField.tsx
├── LoadingButton.tsx
└── PageHeader.tsx
#ใช้ Theme แทน Hard-code สี
ไม่ควร
sx={{
backgroundColor: '#1976d2'
}}
ควรใช้
sx={{
backgroundColor: 'primary.main'
}}
#ใช้ Server-side Pagination
สำหรับข้อมูลจำนวนมาก
Database
↓
Laravel paginate()
↓
Inertia Props
↓
React
↓
MUI Pagination
#20. Production Build
Build Frontend
npm run build
จากนั้น Deploy Laravel ตามปกติ
ตัวอย่าง Production Architecture
Internet
↓
Nginx
↓
PHP-FPM
↓
Laravel
↓
Database
Frontend Asset จะถูก Build ด้วย Vite
#Laravel + MUI เหมาะกับระบบแบบใด
MUI เหมาะกับ Laravel Application ประเภท
- Admin Dashboard
- ERP
- CRM
- Inventory
- Back-office
- Student Information System
- Management System
- Report System
- Data Dashboard
โดยเฉพาะระบบที่มี
Form
Table
Dialog
Dashboard
Data Grid
Search
Pagination
Navigation
#สรุป
การใช้ MUI กับ Laravel เป็นแนวทางที่เหมาะสำหรับการสร้าง Web Application สมัยใหม่ที่ต้องการความสามารถของ Laravel ในฝั่ง Backend และต้องการ Component UI ที่พร้อมใช้งานจาก React Ecosystem
Stack ที่แนะนำคือ
Laravel 13
+
Inertia 3
+
React 19
+
TypeScript
+
Material UI
+
Vite
Data Flow
Route
↓
Controller
↓
Inertia::render()
↓
React Page
↓
MUI Components
↓
User Interface
Laravel ทำหน้าที่จัดการ
Business Logic
Validation
Authentication
Authorization
Database
ส่วน MUI ทำหน้าที่
Presentation Layer
Component
Layout
Form
Table
Dialog
Dashboard
เมื่อแยกหน้าที่ระหว่าง Backend และ Frontend อย่างชัดเจน จะช่วยให้ระบบสามารถพัฒนา ดูแล และขยายต่อได้ง่ายขึ้น
#คำสั่งที่ใช้บ่อย
สร้าง Laravel Project
laravel new laravel-mui
ติดตั้ง Dependency
npm install
ติดตั้ง MUI
npm install @mui/material @emotion/react @emotion/styled
ติดตั้ง Material Icons
npm install @mui/icons-material
ติดตั้ง Roboto Font
npm install @fontsource/roboto
รัน Development
composer run dev
Build Production
npm run build
#เอกสารอ้างอิง
- Laravel Documentation: https://laravel.com/docs
- Laravel Starter Kits: https://laravel.com/starter-kits
- Inertia.js: https://inertiajs.com
- Material UI: https://mui.com/material-ui/
- MUI Installation: https://mui.com/material-ui/getting-started/installation/
- MUI X Data Grid: https://mui.com/x/react-data-grid/