跳到主要内容前端组件库:拒绝重复造轮子,提升开发效率 | 极客日志JavaScript大前端
前端组件库:拒绝重复造轮子,提升开发效率
探讨了前端开发中使用组件库的重要性。通过对比手动编写组件与使用成熟库(如 Ant Design、Material UI、Shadcn UI)的案例,指出手动编写会导致样式不统一和维护困难。推荐使用现有组件库以提升开发效率和代码质量,实现样式统一和功能复用。
机器人6 浏览 前端组件库:拒绝重复造轮子,提升开发效率
行业痛点
近期观察到部分项目存在手动编写所有组件的情况,导致样式不统一、维护困难。这种模式类似于在没有工具的情况下盖房子——虽然可行,但效率极低。
反面案例
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;
上述代码中,每个组件都需要手动编写样式,不仅代码冗余,且难以保证视觉一致性。
推荐方案
1. Ant Design
import React from 'react';
import { Button, Input, Card, Form, Table, , notification } ;
;
() {
[isModalVisible, setIsModalVisible] = .();
= () => ();
= () => {
();
notification.({ : , : });
};
= () => ();
columns = [
{ : , : , : },
{ : , : , : },
{ : , : , : },
];
data = [
{ : , : , : },
{ : , : , : },
];
(
);
}
;
微信扫一扫,关注极客日志
微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
相关免费在线工具
- 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
Modal
from
'antd'
import
'antd/dist/reset.css'
function
App
const
React
useState
false
const
showModal
setIsModalVisible
true
const
handleOk
setIsModalVisible
false
success
message
'成功'
description
'操作成功'
const
handleCancel
setIsModalVisible
false
const
title
'姓名'
dataIndex
'name'
key
'name'
title
'年龄'
dataIndex
'age'
key
'age'
title
'操作'
key
'action'
render
() =>
<Button type="primary">编辑</Button>
const
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 label="年龄" name="age" rules={[{ required: true, message: '请输入年龄' }]}>
<Input type="number" placeholder="请输入年龄" />
</Form.Item>
</Form>
</Modal>
</div>
export
default
App
2. Material UI
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 showModal = () => setIsModalVisible(true);
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={showModal} 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}>
{row.name}
{row.age}
编辑
))}
添加用户
setName(e.target.value)} />
setAge(e.target.value)} />
取消
提交
);
}
export default App;
3. Tailwind CSS + Shadcn UI
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;
使用成熟的组件库能确保统一的样式规范,提供丰富的功能组件,显著提升开发效率,避免重复造轮子的问题。
<TableCell>
</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>