前端组件库:别再重复造轮子了

前端组件库:别再重复造轮子了

毒舌时刻

这组件写得跟拼凑似的,一点都不统一。

各位前端同行,咱们今天聊聊前端组件库。别告诉我你还在手动编写所有组件,那感觉就像在没有工具的情况下盖房子——能盖,但效率低得可怜。

为什么你需要组件库

最近看到一个项目,每个组件都要手动编写,样式不统一,维护困难。我就想问:你是在做组件还是在做重复劳动?

反面教材

// 反面教材:手动编写组件 // Button.jsx 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; // Input.jsx 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; // Card.jsx import React from 'react'; function Card({ children }) { return ( <div style={{ padding: '20px', border: '1px solid #ddd', borderRadius: '4px', boxShadow: '0 2px 4px rgba(0,0,0,0.1)' }} > {children} </div> ); } export default Card; 

毒舌点评:这组件编写,就像在重复造轮子,每个组件都要手动编写样式,效率低得可怜。

正确姿势

1. Ant Design

// 正确姿势:Ant Design // 1. 安装依赖 // npm install antd // 2. 基本使用 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

// 正确姿势:Material UI // 1. 安装依赖 // npm install @mui/material @emotion/react @emotion/styled // 2. 基本使用 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} aria-labelledby="modal-modal-title" aria-describedby="modal-modal-description" > <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

// 正确姿势:Tailwind CSS + Shadcn UI // 1. 安装依赖 // npm install -D tailwindcss postcss autoprefixer // npx tailwindcss init -p // npx shadcn@latest init // 2. 配置 Tailwind CSS // tailwind.config.js /** @type {import('tailwindcss').Config} */ export default { content: [ "./index.html", "./src/**/*.{js,ts,jsx,tsx}", ], theme: { extend: {}, }, plugins: [], } // 3. 基本使用 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; 

毒舌点评:这才叫前端组件库,统一的样式,丰富的组件,开发效率高,再也不用担心重复造轮子的问题了。

Read more

前端测试(一)Web基础

一、javaweb工程 1.javaweb工程概述 JavaWeb应用指供浏览器访问的程序,通常也简称为web应用。 一个web应用由多个静态web资源(html css js)和动态web资源(实现功能)组成,例如:html、css、js文件,jsp文件、java程序、支持jar包、工程配置文件、图片、音视频等等。 Web应用开发好后,若想供外界访问,需要把web应用所在目录交给Web服务器管理(如:Tomca等),这个过程称之为虚似目录的映射,即web工程目录物理路径映射编程网络访问路径(虚拟目录)。 2.javaweb工程目录结构 Maven构建JavaWeb工程的标准目录 项目根目录/ ├── pom.xml # Maven核心配置文件 ├── src/ │ ├── main/ # 主代码目录 │ │ ├── java/ # Java源代码目录 │ │ │ └── com/example/ # 包目录结构 │ │ │ ├── controller/ # 控制器类 │ │ │ ├── service/ # 业务逻辑接口

GLM-4.6V-Flash-WEB与Qwen-VL对比:视觉理解部署评测

GLM-4.6V-Flash-WEB与Qwen-VL对比:视觉理解部署评测 1. 引言 随着多模态大模型在图像理解、图文生成等任务中的广泛应用,视觉语言模型(Vision-Language Model, VLM)已成为AI工程落地的重要方向。近期,智谱AI推出了轻量级开源视觉大模型 GLM-4.6V-Flash-WEB,主打“网页+API”双推理模式,宣称可在单卡环境下高效部署。与此同时,通义千问系列的 Qwen-VL 也凭借其强大的图文理解能力和开放生态受到广泛关注。 本文将从模型特性、部署流程、推理性能、应用场景和开发友好性五个维度,对 GLM-4.6V-Flash-WEB 与 Qwen-VL 进行系统性对比评测,帮助开发者在实际项目中做出更合理的技术选型。 2. 模型特性对比 2.1 GLM-4.6V-Flash-WEB 核心特点 GLM-4.6V-Flash-WEB 是基于 GLM-4V 系列优化的轻量化版本,专为边缘端和本地化部署设计,具备以下关键特征:

WebAssembly:重塑Web与原生边界的革命性字节码——深度技术全景解析

WebAssembly:重塑Web与原生边界的革命性字节码——深度技术全景解析

在浏览器中运行高性能游戏、在网页里直接编辑4K视频、将C++科学计算库无缝嵌入React应用……这些曾被视为“不可能”的场景,如今正因 WebAssembly(Wasm) 的崛起而成为现实。作为继HTML、CSS、JavaScript之后的第四大Web核心技术,WebAssembly不仅打破了“Web性能天花板”,更正在模糊Web应用与原生应用的边界,开启全栈开发的新纪元。 本文将从设计哲学、核心机制、编译流程、应用场景到未来演进,为你提供一份全面、深入、实战导向的WebAssembly终极指南。 一、为什么需要 WebAssembly?JavaScript 的性能瓶颈 尽管现代JS引擎(V8、SpiderMonkey)通过JIT编译极大提升了性能,但JavaScript作为动态类型、解释执行的语言,在以下场景仍存在先天不足: * CPU密集型计算(如图像处理、物理仿真、加密解密); * 内存敏感操作(如大型数组、手动内存管理); * 复用现有C/C++/Rust代码库(如FFmpeg、TensorFlow、Unity引擎)

Alpamayo-R1-10B部署教程:/etc/supervisor/conf.d下WebUI端口自定义修改实录

Alpamayo-R1-10B部署教程:/etc/supervisor/conf.d下WebUI端口自定义修改实录 1. 项目概述 Alpamayo-R1-10B是专为自动驾驶研发设计的开源视觉-语言-动作(VLA)模型,具备100亿参数规模。该模型通过整合AlpaSim模拟器与Physical AI AV数据集,构建了完整的自动驾驶研发工具链。其核心价值在于通过类人因果推理机制,显著提升自动驾驶决策的可解释性,特别是在处理长尾场景时展现出优异的适应能力。 2. 环境准备 2.1 硬件要求 * GPU配置:至少需要NVIDIA RTX 4090 D级别显卡(22GB显存) * 内存需求:推荐32GB以上系统内存 * 存储空间:需预留30GB以上可用空间 2.2 软件依赖 # 基础环境检查 nvidia-smi # 确认GPU驱动正常 python --version # 需Python 3.12 supervisord --version # 需Supervisor 4.x 3.