开发编程
#react
ui-frontend
React 前端 UI 组件开发技能,指导 Tauri 桌面应用的界面开发。 触发场景: - 需要开发 React 页面或组件 - 需要选择和使用 UI 组件库 - 需要处理表单、表格、弹窗等常见 UI - 需要实现响应式布局 触发词: UI、组件、页面、前端、界面、表单、表格、弹窗、布局、样式、React
DeepseekModel
官方收录技能
质量 优秀 · 78
v1.0.0
获取
https://deepseekmodel.com/api/download.php?id=bkywksj-knowledge-base-claude-skills-ui-frontend-skill-md&format=skill
下载 .skill
标准格式,含 system_prompt 与 model_config,导入任意 Agent 框架即可使用
.skill 文件中 system_prompt 字段的实际内容。
name ui-frontend description React 前端 UI 组件开发技能,指导 Tauri 桌面应用的界面开发。 触发场景: - 需要开发 React 页面或组件 - 需要选择和使用 UI 组件库 - 需要处理表单、表格、弹窗等常见 UI - 需要实现响应式布局 触发词: UI、组件、页面、前端、界面、表单、表格、弹窗、布局、样式、React React 前端 UI 开发 概述 Tauri 桌面应用的前端运行在系统 WebView 中,使用 React 19 + TypeScript 5.8 + Ant Design + TailwindCSS 4 开发。与 Web 应用的主要区别是:窗口大小可控、无需考虑 SEO、可调用系统 API。 前端项目结构 src/ ├── components/ │ ├── layout/ │ │ ├── AppLayout.tsx # 主布局(Ant Design Layout) │ │ └── Sidebar.tsx # 侧边栏导航 │ └── ui/ │ └── ErrorBoundary.tsx # 错误边界 ├── hooks/ │ └── useCommand.ts # invoke 封装 ├── lib/ │ └── api/ │ └── index.ts # API 类型安全封装 ├── pages/ │ ├── home/index.tsx # 首页 │ ├── settings/index.tsx # 设置页 │ └── about/index.tsx # 关于页 ├── store/ │ └── index.ts # Zustand 全局状态 ├── styles/ │ └── global.css # TailwindCSS ├── types/ │ └── index.ts # TS 类型 ├── App.tsx # 根组件(ConfigProvider + Router) ├── Router.tsx # React Router 配置 └── main.tsx # 入口 当前技术栈 技术 用途 Ant Design UI 组件库(Layout/Form/Table 等) TailwindCSS 4 原子化 CSS 样式 React Router 客户端路由 Zustand 全局状态管理 UI 组件库(已选用 Ant Design) 项目已集成 Ant Design 作为主要 UI 组件库,配合 TailwindCSS 4 做原子化样式补充。 关键组件 用途 参考文件 Layout / Sider / Content 主布局 src/components/layout/AppLayout.tsx Menu 侧边栏导航 src/components/layout/Sidebar.tsx ConfigProvider 全局主题配置 src/App.tsx Form / Input / Select 表单 各页面组件 Table 数据表格 各页面组件 Modal / message 弹窗/消息 各页面组件 组件开发模式 基础组件模板 import { useState } from "react" ; import { invoke } from "@tauri-apps/api/core" ; interface Props { title : string ; } function FeaturePage ( { title }: Props ) { const [data, setData] = useState< DataType []>([]); const [loading, setLoading] = useState ( false ); const [error, setError] = useState< string | null >( null ); async function loadData ( ) { setLoading ( true ); setError ( null ); try { const result = await invoke< DataType []>( "get_data" ); setData (result); } catch (e) { setError ( String (e)); } finally { setLoading ( false ); } } if (loading) return < div className = "loading" > 加载中... </ div > ; if (error) return < div className = "error" > 错误: {error} </ div > ; return ( < div className = "page" > < h1 > {title} </ h1 > < div className = "content" > {data.map(item => ( < div key = {item.id} > {item.name} </ div > ))} </ div > </ div > ); } export default FeaturePage ; 表单组件 import { useState, FormEvent } from "react" ; import { invoke } from "@tauri-apps/api/core" ; interface FormData { name : string ; email : string ; description : string ; } function CreateForm ( ) { const [form, setForm] = useState< FormData >({ name : "" , email : "" , description : "" }); function handleChange ( field : keyof FormData , value : string ) { setForm ( prev => ({ ...prev, [field]: value })); } async function handleSubmit ( e : FormEvent ) { e. preventDefault (); try { await invoke ( "create_item" , { input : form }); setForm ({ name : "" , email : "" , description : "" }); } catch (e) { alert ( `保存失败: ${e} ` ); } } return ( < form onSubmit = {handleSubmit} > < label > 名称 < input value = {form.name} onChange = {e => handleChange("name", e.target.value)} required /> </ label > < label > 邮箱 < input type = "email" value = {form.email} onChange = {e => handleChange("email", e.target.value)} /> </ label > < label > 描述 < textarea value = {form.description} onChange = {e => handleChange("description", e.target.value)} /> </ label > < button type = "submit" > 保存 </ button > </ form > ); } 列表 + CRUD 页面 function ItemList ( ) { const [items, setItems] = useState< Item []>([]); const [editing, setEditing] = useState< Item | null >( null ); useEffect ( () => { loadItems (); }, []); async function loadItems ( ) { const list = await invoke< Item []>( "list_items" ); setItems (list); } async function deleteItem ( id : number ) { if (! confirm ( "确认删除?" )) return ; await invoke ( "delete_item" , { id }); await loadItems (); } return ( < div > < table > < thead > < tr > < th > ID </ th > < th > 名称 </ th > < th > 操作 </ th > </ tr > </ thead > < tbody > {items.map(item => ( < tr key = {item.id} > < td > {item.id} </ td > < td > {item.name} </ td > < td > < button onClick = {() => setEditing(item)}>编辑 </ button > < button onClick = {() => deleteItem(item.id)}>删除 </ button > </ td > </ tr > ))} </ tbody > </ table > </ div > ); } 桌面应用 UI 注意事项 注意事项 说明 窗口大小 默认 800x600,可在 tauri.conf.json 配置 无滚动条 桌面应用通常避免页面级滚动 系统菜单 可通过 Tauri Menu API 实现原生菜单 拖拽区域 使用 data-tauri-drag-region 创建可拖拽标题栏 快捷键 可通过 Tauri 全局快捷键 API 注册 深色模式 使用 CSS prefers-color-scheme 媒体查询 常见错误 错误做法 正确做法 使用 window.alert() 使用自定义弹窗组件或 Tauri dialog 插件 使用 window.open() 使用 Tauri 窗口 API 或 opener 插件 不考虑深色模式 使用 CSS 变量 + prefers-color-scheme 使用绝对像素布局 使用 flexbox/grid 响应式布局 组件过大不拆分 按功能拆分为 < 200 行的小组件 悬停提示统一(原生 title → AntD Tooltip) 🔴 本项目全站禁用浏览器原生 title 黄条 。 src/App.tsx 挂了全局 src/components/GlobalNativeTooltip.tsx : 捕获阶段监听 hover,把 任意元素的 title 一次性「借走」存到 data-native-title (浏览器从此不弹黄条)+ 补 aria-label , 再用 受控 AntD Tooltip 在该元素矩形上渲染同款深色气泡(跟随主题,150ms 延迟防扫过狂闪)。 只作用于「带 title 特性的 DOM 元素」;AntD 自己的 Tooltip/Modal/Drawer 触发器上没有 title 特性 → 零冲突、零布局改动 。 新写交互提示:直接给元素加 title="文案" 即可自动升级成气泡 (面向未来,不用逐个手包 <Tooltip> )。 需要 富文本 / 受控 open / 动态文案 时才显式用 AntD <Tooltip> ( placement + mouseEnterDelay={0.2} )。 ❌ 别再留原生黄条,也别逐个手包 Tooltip。
Agent 识别该技能的关键词,点击任意一个即可复制。
该技能未提供触发词。
下载的 .skill 包内含以下字段。
| 字段 | 说明 |
|---|---|
| format | 格式标识(skill/v1) |
| skill_id | 技能唯一 ID |
| name | 技能名称 |
| version | 版本号 |
| description | 技能描述 |
| category | 所属分类(数组) |
| trigger_words | 触发词列表 |
| tags | 标签列表 |
| source | 来源标识 |
| source_url | 来源链接(本页地址) |
| exported_at | 导出时间(每次下载生成) |
| system_prompt | 系统提示词正文 |
| model_config | 模型参数:provider / model / temperature / max_tokens / top_p |
| examples | 示例 |
| install_guide | 各平台导入说明(Coze / Dify / Claude / 自定义框架) |