跳到主要内容前端组件库实战:告别重复造轮子 | 极客日志JavaScript大前端
前端组件库实战:告别重复造轮子
综述由AI生成前端开发中,手动编写基础组件往往导致样式不统一、维护成本高。对比了原生手写与主流组件库(Ant Design、Material UI、Tailwind + Shadcn)的差异,展示了如何利用成熟方案提升开发效率并保证一致性。通过实际代码示例,分析了不同技术栈下的最佳实践,帮助开发者在项目中合理选型,避免低效的重复劳动。
独立开发者13 浏览 前端组件库实战:告别重复造轮子
常见误区
很多项目里,我们常看到这样的代码:每个按钮、输入框都是手写样式,不仅维护困难,还导致界面风格割裂。这就像在没有工具的情况下盖房子——能盖,但效率低得可怜。
为什么你需要组件库
最近接手过一个项目,每个组件都要手动编写,样式不统一,维护成本极高。如果还在手动编写所有基础组件,本质上是在做重复劳动,而非真正的业务开发。
反面教材:原生手写组件
import React from 'react';
function Button({ children, onClick }) {
return (
<button
onClick={onClick}
style={{
padding: '10px 20px',
backgroundColor: '#007bff',
color: '#fff',
border: 'none',
borderRadius: '4px',
cursor: 'pointer'
}}
>
{children}
</button>
);
}
export default Button;
import React from 'react';
function Input({ value, onChange, placeholder }) {
return (
<
=
=
=
=
=
'',
' #',
'',
'%'
}}
/>
);
}
;
input
type
"text"
value
{value}
onChange
{onChange}
placeholder
{placeholder}
style
{{
padding:
10px
border:
1px
solid
ddd
borderRadius:
4px
width:
100
export
default
Input
这种写法最大的问题在于样式散落在各个组件内部,一旦需求变更,需要逐个修改,极易遗漏。
主流解决方案
1. Ant Design
import React from 'react';
import { Button, Input, Card, Form, Table, Modal, notification } from 'antd';
import 'antd/dist/reset.css';
function App() {
const [isModalVisible, setIsModalVisible] = React.useState(false);
const showModal = () => setIsModalVisible(true);
const handleOk = () => {
setIsModalVisible(false);
notification.success({ message: '成功', description: '操作成功' });
};
const handleCancel = () => setIsModalVisible(false);
const columns = [
{ title: '姓名', dataIndex: 'name', key: 'name' },
{ title: '年龄', dataIndex: 'age', key: 'age' },
{ title: '操作', key: 'action', render: () => <Button type="primary">编辑</Button> }
];
const data = [
{ key: '1', name: '张三', age: 32 },
{ key: '2', name: '李四', age: 42 }
];
return (
<div style={{ padding: '20px' }}>
<Card title="用户管理">
<Button type="primary" onClick={showModal} style={{ marginBottom: '20px' }}>
添加用户
</Button>
<Table columns={columns} dataSource={data} />
</Card>
<Modal title="添加用户" open={isModalVisible} onOk={handleOk} onCancel={handleCancel}>
<Form>
<Form.Item label="姓名" name="name" rules={[{ required: true, message: '请输入姓名' }]}>
<Input placeholder="请输入姓名" />
</Form.Item>
<Form.Item = = = , '' }]}>
);
}
export default App;
2. Material UI
遵循 Google Material Design 规范,适合追求设计一致性的项目。
import React from 'react';
import {
Button, TextField, Card, CardContent, Table, TableBody,
TableCell, TableContainer, TableHead, TableRow, Paper, Modal, Box
} from '@mui/material';
function App() {
const [isModalVisible, setIsModalVisible] = React.useState(false);
const [name, setName] = React.useState('');
const [age, setAge] = React.useState('');
const handleClose = () => setIsModalVisible(false);
const handleSubmit = () => {
console.log('提交:', { name, age });
setIsModalVisible(false);
};
const rows = [
{ id: 1, name: '张三', age: 32 },
{ id: 2, name: '李四', age: 42 }
];
return (
<div style={{ padding: '20px' }}>
<Card sx={{ mb: 2 }}>
<CardContent>
<Button variant="contained" color="primary" onClick={() => setIsModalVisible(true)} sx={{ mb: 2 }}>
添加用户
</Button>
<TableContainer component={Paper}>
<Table>
<TableHead>
<TableRow>
<TableCell>姓名</TableCell>
<TableCell>年龄</TableCell>
<TableCell>操作</TableCell>
</TableRow>
</TableHead>
<TableBody>
{rows.map((row) => (
<TableRow key={row.id}>
<TableCell>{row.name}
{row.age}
编辑
))}
添加用户
setName(e.target.value)} />
setAge(e.target.value)} />
取消
提交
);
}
export default App;
3. Tailwind CSS + Shadcn UI
现代前端趋势,原子化 CSS 配合可复用组件,灵活性极高。
import React from 'react';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import { Table, TableBody, TableCell, TableHead, TableRow } from '@/components/ui/table';
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogTrigger } from '@/components/ui/dialog';
import { Label } from '@/components/ui/label';
function App() {
const rows = [
{ id: 1, name: '张三', age: 32 },
{ id: 2, name: '李四', age: 42 }
];
return (
<div className="p-4">
<Card className="mb-4">
<CardHeader>
<CardTitle>用户管理</CardTitle>
</CardHeader>
<CardContent>
<Dialog>
<DialogTrigger asChild>
<Button className="mb-4">添加用户</Button>
</DialogTrigger>
<DialogContent className="sm:max-w-md">
<DialogHeader>
<DialogTitle>添加用户</DialogTitle>
</DialogHeader>
<div className="grid gap-4 py-4">
<div className="grid gap-2">
<Label htmlFor="name">姓名</Label>
<Input placeholder= />
年龄
取消
提交
姓名
年龄
操作
{rows.map((row) => (
{row.name}
{row.age}
编辑
))}
);
}
export default App;
核心建议
这才叫前端组件库:统一的样式语言,丰富的开箱即用组件,开发效率高,再也不用担心重复造轮子的问题了。根据团队技术栈和项目规模选择合适的方案,能让后续迭代事半功倍。
label
"年龄"
name
"age"
rules
{[{
required:
true
message:
请输入年龄
<Input type="number" placeholder="请输入年龄" />
</Form.Item>
</Form>
</Modal>
</div>
</TableCell>
<TableCell>
</TableCell>
<TableCell>
<Button variant="outlined" color="primary">
</Button>
</TableCell>
</TableRow>
</TableBody>
</Table>
</TableContainer>
</CardContent>
</Card>
<Modal open={isModalVisible} onClose={handleClose}>
<Box sx={{ position: 'absolute', top: '50%', left: '50%', transform: 'translate(-50%, -50%)', width: 400, bgcolor: 'background.paper', border: '2px solid #000', boxShadow: 24, p: 4 }}>
<h2>
</h2>
<TextField label="姓名" fullWidth value={name} onChange={(e) =>
<TextField label="年龄" type="number" fullWidth value={age} onChange={(e) =>
<Box sx={{ mt: 2, display: 'flex', justifyContent: 'flex-end', gap: 1 }}>
<Button onClick={handleClose}>
</Button>
<Button variant="contained" color="primary" onClick={handleSubmit}>
</Button>
</Box>
</Box>
</Modal>
</div>
"请输入姓名"
</div>
<div className="grid gap-2">
<Label htmlFor="age">
</Label>
<Input type="number" placeholder="请输入年龄" />
</div>
</div>
<div className="flex justify-end gap-2">
<Button variant="secondary">
</Button>
<Button>
</Button>
</div>
</DialogContent>
</Dialog>
<div className="overflow-auto">
<Table>
<TableHead>
<TableRow>
<TableCell>
</TableCell>
<TableCell>
</TableCell>
<TableCell>
</TableCell>
</TableRow>
</TableHead>
<TableBody>
<TableRow key={row.id}>
<TableCell>
</TableCell>
<TableCell>
</TableCell>
<TableCell>
<Button variant="secondary">
</Button>
</TableCell>
</TableRow>
</TableBody>
</Table>
</div>
</CardContent>
</Card>
</div>
相关免费在线工具
- Keycode 信息
查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online
- Escape 与 Native 编解码
JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online
- JavaScript / HTML 格式化
使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online
- JavaScript 压缩与混淆
Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online
- Base64 字符串编码/解码
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
- Base64 文件转换器
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online