阅读视图

发现新文章,点击刷新页面。

*** 都不用tailwind!!!哎嘛 真香😘😘😘

🎯 前言

刚入职新公司,老板就给了我一个“惊喜”任务:
老板:“需要根据现有后台系统,做个新的后台系统,好看点、大气点、不要太模板化,对了用 React。”
:“???没有 UI、没有产品。我尼玛*** ***”

下载.jpg

💩 了解旧版系统

旧版系统是 Vue3 + ant-design-vue 做的,一个巨大的“屎山”直接丢了过来。几个比较严重的问题:

  1. 代码质量极差:完全没有组件化可言,所有页面都是一坨一坨的代码堆在一起
  2. UI 设计极差:应该也是没有设计师,完全靠前端随意发挥(主题配色红配绿、乱七八糟的字体大小、间距)
  3. 功能逻辑混乱:代码注释极少,完全看不懂业务逻辑
  4. 后端也是一坨屎:接口设计差,前后端配合差,很多东西都是前端做的兼容/硬编码等等

代码是老板不知道从哪里弄来的压缩包。如上所示,“屎山”把我压得喘不过气。我有时候真想找到之前写这个代码的人骂一顿(没有 Git 记录也不知道是谁)。这个代码存在的唯一价值就是主流程能跑,或许这就是小公司老板所关心的吧。

下载 (2).jpg

🧠 思考架构

没有 UI、产品,我真的是一头雾水,不知道该如何下手。只能先把旧版系统的功能理清楚,然后一步步实现。因为老板要求用 React,正好我之前用 React 自己搭建了一套后台管理模板(文章链接),它是基于 Ant Design 的一套系统,有兴趣的可以去看看。

🚀 开始实现

由于我之前搭建的 React 后台模板已经比较完善了,所以我直接拿来用。然后一步步把旧版系统的功能搬过来,并且升级了一些依赖版本等等。老板要求的一个重点是不要太“模板化”,我一直思考应该怎么样去处理和优化。

由于没有设计师,我只能凭借我的审美去调整一些 UI 细节,比如配色、字体、间距、图标等等。总之就是尽量让它看起来不那么像一个模板系统。初版如下图:

react_antd_示例图.png

上图的 UI,我都有微调过包括字体、图标、间距等等,让它看起来不那么“模板化”。奈何有天老板从我旁边过,看了一眼说:“你是用的 Antd 吗?能不能搞得不那么模板化,看着还是太大众了。”当时我内心真的想骂人,辛辛苦苦做的工作就这样被一句话否定了,而且又没 UI、又没产品。

下载 (3).jpg

🔄 重新出发

没办法,谁让人家是老板,还是照做。我在网上有看到过 shadcn/ui 这个组件库的,它是基于 TailwindCSS,我本人是非常厌恶这个玩意的:

  1. 因为上一家公司有个同事在项目里使用TailwindCSS,满屏的 classname,看得我头皮发麻。想要改一个样式都不知道从哪下手
  2. shadcn/ui 和我认知里的 Antd Pro 是完全不同的设计体系。比如在 Antd Pro 里写一个表格,请求接口拿到数据喂给 Table 就行了。但是在 shadcn/ui 里你得自己写分页、排序、筛选这些功能。你得自己实现很多功能,会导致我的工作量大增。虽然现在都用 AI 编码了,但是我还是觉得很麻烦

但是由于我知道 TailwindCSS 的流行趋势,且确实 shadcn/ui 的可定制化更高一点,所以还是决定用 shadcn/ui 来重构。但是时间紧、任务重,我想从网上找找有没有现成的可以二开的 shadcn 后台模板。结果发现了这个项目:shadcn-admin。里面封装好了 Table、Layout 等功能且支持移动端。推荐给各位,太香啦!

🛠️ 技术栈

  • React 19
  • TypeScript
  • TanStack 家族(@tanstack/react-query、@tanstack/react-router、@tanstack/react-table)
  • shadcn/ui
  • TailwindCSS
  • Zustand
  • Zod
  • react-hook-form 等

🔧 集成适配

虽说是现成的模板,但是有一些功能没有、或者需要根据业务适配。比如国际化、Table 远程数据请求(模板是本地模拟数据)等。

🎨 最终形态

image.png

📌 总结

这一套新兴模板,上手还是有点难度的(比如 TanStack 家族、shadcn/ui)。TanStack 体系庞大,shadcn 定制化高(功能都要自己实现)。但是目前 AI 盛行,资料也是大把,相信对你来说也都是小菜一碟。

💭 最后

Tailwind 还是挺香的,我觉得它是一把双刃剑。我的前同事(Tailwind 写 class 十几、几十行)确实给维护的人增加心智负担,但是也可以通过一些技术手段改善和优化。这取决于用它的人是怎样的。

下载 (4).jpg

❌