React.js实现适配Tailwind UI的树形视图与表格组件需求咨询
基于Tailwind的UI组件交付方案
通用适配规则
- 完全适配Tailwind UI官方设计规范,兼容现有亮色/暗色模式风格
- 采用移动优先的响应式设计,自动适配手机、平板、桌面端全尺寸屏幕
1. 树形视图(Tree)组件
功能特性
- 层级动态适配:无固定层级限制,完全匹配传入数据的层级结构,数据为3级则渲染3级、5级则渲染5级
- 异步子节点加载:点击节点前置的
+按钮时触发异步请求,请求返回后自动渲染子级记录,无需整体刷新树结构
核心实现代码
// Tree组件核心逻辑示例 import { useState } from 'react' const TreeItem = ({ node, loadChildren }) => { const [isOpen, setIsOpen] = useState(false) const [children, setChildren] = useState([]) const [loading, setLoading] = useState(false) const toggleExpand = async () => { if (!isOpen && node.hasChildren && children.length === 0) { setLoading(true) const res = await loadChildren(node.id) setChildren(res) setLoading(false) } setIsOpen(!isOpen) } return ( <div className="pl-4"> <div className="flex items-center gap-2 py-1.5 text-sm text-gray-800 dark:text-gray-200"> {node.hasChildren && ( <button onClick={toggleExpand} className="w-5 h-5 flex items-center justify-center rounded hover:bg-gray-100 dark:hover:bg-gray-700 transition-colors" > {loading ? '⋯' : isOpen ? '−' : '+'} </button> )} <span>{node.label}</span> </div> {isOpen && children.length > 0 && ( <div> {children.map(child => ( <TreeItem key={child.id} node={child} loadChildren={loadChildren} /> ))} </div> )} </div> ) } export default TreeItem
2. 表格展示组件(Table Display)
功能特性
- 视觉风格:极简现代设计,通过阴影、边框、hover态区分层级,质感清晰
- 列宽调整:支持拖拽表头边界手动调整每列宽度,调整后自动适配内容展示
- 大数据兼容:内置虚拟滚动能力,支持上万条数据行流畅滚动浏览,无卡顿
- 完整分页:配备全功能分页导航,包含首页、上一页、页码选择、下一页、末页、每页条数调整入口
核心实现代码
// 分页组件核心示例 const Pagination = ({ current, total, pageSize, onChange }) => { const totalPage = Math.ceil(total / pageSize) return ( <div className="flex flex-wrap items-center justify-between gap-2 px-4 py-3 border-t border-gray-200 dark:border-gray-700"> <div className="text-sm text-gray-600 dark:text-gray-400"> 共 {total} 条记录,每页 {pageSize} 条 </div> <div className="flex items-center gap-2"> <button onClick={() => onChange(1)} disabled={current === 1} className="px-3 py-1 rounded border border-gray-200 dark:border-gray-700 disabled:opacity-50 hover:bg-gray-100 dark:hover:bg-gray-700 text-sm transition-colors" > 首页 </button> <button onClick={() => onChange(current - 1)} disabled={current === 1} className="px-3 py-1 rounded border border-gray-200 dark:border-gray-700 disabled:opacity-50 hover:bg-gray-100 dark:hover:bg-gray-700 text-sm transition-colors" > 上一页 </button> <span className="text-sm px-2">{current} / {totalPage}</span> <button onClick={() => onChange(current + 1)} disabled={current === totalPage} className="px-3 py-1 rounded border border-gray-200 dark:border-gray-700 disabled:opacity-50 hover:bg-gray-100 dark:hover:bg-gray-700 text-sm transition-colors" > 下一页 </button> <button onClick={() => onChange(totalPage)} disabled={current === totalPage} className="px-3 py-1 rounded border border-gray-200 dark:border-gray-700 disabled:opacity-50 hover:bg-gray-100 dark:hover:bg-gray-700 text-sm transition-colors" > 末页 </button> </div> </div> ) }
内容的提问来源于stack exchange,提问作者dev-ninja
相关产品推荐
相关产品推荐

