跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客GitHub 精选镜像AI 生图工具UI配色美学隐私政策关于联系
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
JavaScript大前端

前端组件库:拒绝重复造轮子,提升开发效率

探讨了前端开发中使用组件库的重要性。通过对比手动编写组件与使用成熟库(如 Ant Design、Material UI、Shadcn UI)的案例,指出手动编写会导致样式不统一和维护困难。推荐使用现有组件库以提升开发效率和代码质量,实现样式统一和功能复用。

机器人发布于 2026/4/6更新于 2026/7/537 浏览

前端组件库:拒绝重复造轮子,提升开发效率

行业痛点

近期观察到部分项目存在手动编写所有组件的情况,导致样式不统一、维护困难。这种模式类似于在没有工具的情况下盖房子——虽然可行,但效率极低。

反面案例

// 反面案例:手动编写组件
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
// 安装依赖
// npm install antd

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 label="年龄" name="age" rules={[{ required: true, message: '请输入年龄' }]}>
            <Input type="number" placeholder="请输入年龄" />
          </Form.Item>
        </Form>
      </Modal>
    </div>
  );
}

export default App;
2. Material UI
// 安装依赖
// npm install @mui/material @emotion/react @emotion/styled

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}>
                    <TableCell>{row.name}</TableCell>
                    <TableCell>{row.age}</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) => setName(e.target.value)} />
          <TextField label="年龄" type="number" fullWidth value={age} onChange={(e) => setAge(e.target.value)} />
          <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>
  );
}

export default App;
3. Tailwind CSS + Shadcn UI
// 安装依赖
// npm install -D tailwindcss postcss autoprefixer
// npx tailwindcss init -p
// npx shadcn@latest init

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="请输入姓名" />
                </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>
                {rows.map((row) => (
                  <TableRow key={row.id}>
                    <TableCell>{row.name}</TableCell>
                    <TableCell>{row.age}</TableCell>
                    <TableCell>
                      <Button variant="secondary">编辑</Button>
                    </TableCell>
                  </TableRow>
                ))}
              </TableBody>
            </Table>
          </div>
        </CardContent>
      </Card>
    </div>
  );
}

export default App;

使用成熟的组件库能确保统一的样式规范,提供丰富的功能组件,显著提升开发效率,避免重复造轮子的问题。

目录

  1. 前端组件库:拒绝重复造轮子,提升开发效率
  2. 行业痛点
  3. 反面案例
  4. 推荐方案
  5. 1. Ant Design
  6. 2. Material UI
  7. 3. Tailwind CSS + Shadcn UI
  • 免费图片AI生成工具免费生成了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 免费图片视频在线生成30秒,将你的创意变成现实开始设计
  • X/Twitter免费视频下载器免登陆无限额度免费视频解析下载了解详情
  • 100+免费在线小游戏爽一把
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • 算法:双指针法详解(上)
  • Python 屏幕截图翻译工具实战
  • 字节前端一面面经解析:网络原理、Vue 及手写题详解
  • 6 层高速 PCB 设计实战:逻辑派 FPGA-G1 开发板布局布线详解
  • 前端权限管理实现方案与最佳实践
  • 区块链共识算法:时间长河(Time River Consensus Algorithm)
  • 无人机视角山区泥石流和滑坡图像识别数据集
  • 基于人类反馈的强化学习(RLHF)全解析
  • Ubuntu Edgy Eft 完整软件源列表配置指南
  • 文心大模型 4.5 开源部署实战与中文场景应用
  • Python 语音识别结合 Appium 实现抖音自动化操作
  • HarmonyOS 底部导航栏组件 rc_concave_tabbar 使用指南
  • Android WebView 开发指南:AgentWeb 完整使用
  • 从 AI 绘图到 AI 视频:2026 内容创作者进阶之路
  • ERNIE-4.5-VL-28B-A3B-Paddle 与 DeepSeek-R1 多维度测评分析
  • 利用文心一言为智能体设计稳定的工作流提示词
  • 前端国际化最佳实践与实现方案
  • 基于 Coze 构建专属 AI 应用:从智能体开发到 Web 部署实战
  • Python 零基础学习指南
  • 人工智能(AI)常见面试题及答案汇总

相关免费在线工具

  • 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