🔥 第一次在 React 项目中用 UnoCSS,这些坑我都踩了

入职第一周,我接了个新功能开发任务,正好有机会在项目里第一次上手 UnoCSS。 从引入、配置、实战使用到踩坑总结,这篇文章记录了我整个真实的使用过程,顺便分享一些经验和小技巧。


🧩 项目背景

我最近刚加入一家新公司,前端项目整体技术栈是 React + TypeScript + Vite,这次接手的新项目页面结构偏组件化,样式需求也不少。

公司之前在某些项目里尝试过 UnoCSS,但还没有大规模落地,这次正好借着新功能上线的机会,我也想趁机实战一把。 说实话,在真正动手用之前,我对原子化 CSS 一直有点抗拒:看着那一串串类名,总觉得乱,觉得"和写 style inline 没区别"。

不过这次我强行逼自己用上 UnoCSS,结果还挺香的。


🤔 为什么选择 UnoCSS?

虽然是新项目开发,样式量不算特别大,但要写得快、写得整洁、还要便于后续复用和维护,对样式方案的选择其实挺关键的。

调研阶段我也对比过几种方案:

样式方案 优点 缺点
SCSS / Less 成熟稳定,可自由写嵌套和变量 维护麻烦,类名容易重复,拆组件样式时要引入多个文件
CSS Modules 样式隔离,适合组件化 类名仍需维护,重复样式不易复用
Tailwind CSS 原子化、文档多、社区活跃 类名前缀多、需预定义主题、类名拼接繁琐
UnoCSS 类名极简、按需生成、配置灵活 学习成本稍高,文档偏底层,踩坑多

最终我选择了 UnoCSS,原因主要有 3 点:

  1. 按需生成类名,无需手动维护样式文件,更贴合组件开发节奏;
  2. vite 插件方式接入,配置极其轻量,基本无需额外操作;
  3. 可高度定制,可以自己写规则,自定义 class 变得更加简单。

一句话总结:想写得快、样式简单、还能灵活扩展,就选 UnoCSS。


⚙️ UnoCSS 是怎么引入项目的?

因为项目用的是 Vite + React,使用了 pnpm 管理,接入 UnoCSS 基本不费劲,几步就搞定了。

安装依赖:

ts 复制代码
pnpm add -D unocss

vite.config.ts 中添加插件:

ts 复制代码
import UnoCSS from 'unocss/vite'
​
export default defineConfig({
  plugins: [react(), UnoCSS()]
})

加几个常用 preset:

ts 复制代码
import { presetUno, presetIcons } from 'unocss'
​
UnoCSS({
  presets: [
    presetUno(),
    presetIcons()
  ]
})

我没有启用 attributify 模式,还是采用传统的 className 写法,这样团队其他人更容易接入。


💡 实际开发中怎么用?(Demo 示例)

UnoCSS 的写法跟 Tailwind 类似,但不需要提前扫描、构建就能直接生效,写起来轻松很多。

以下是我在 Demo 中使用 UnoCSS 的一些示例:

页面结构 + 样式一把梭

ts 复制代码
<div className="p-4 bg-white rounded shadow-md flex items-center justify-between">
  <span className="text-lg font-bold text-gray-800">标题</span>
</div>

按钮 hover 效果一把梭

ts 复制代码
<button className="bg-blue-500 hover:bg-blue-600 text-white px-4 py-2 rounded">
  提交
</button>

响应式断点也拿捏

ts 复制代码
<div className="text-sm sm:text-base md:text-lg lg:text-xl">
  响应式文字大小
</div>

不用写 CSS 文件、也不需要维护类名、不担心污染,直接 className 组合就完事了。

除了常规写法外,UnoCSS 还支持非常强大的自定义规则,下面分享我项目中用到的一个实际例子。

✨ 自定义规则增强灵活性

UnoCSS 最让我惊喜的一点就是可以自定义规则。比如这次项目里有个地方要"多行文本省略",传统写法又臭又长。

我就直接在 uno.config.ts 里自定义了一个工具类:

ts 复制代码
// uno.config.ts
export default defineConfig({
  rules: [
    // 多行文本截断工具类
    [
      /^text-truncate-(\d+)$/,
      ([, lines]) => ({
        display: '-webkit-box',
        '-webkit-line-clamp': lines,
        '-webkit-box-orient': 'vertical',
        overflow: 'hidden',
        'text-overflow': 'ellipsis',
      }),
    ],
  ],
})

用的时候也很丝滑:

ts 复制代码
<p className="text-truncate-2">
  这是一个超长段落,将会被两行截断,超出的部分显示省略号......
</p>

是不是比用 SCSS 写变量还方便?尤其适合这种一劳永逸型的通用样式。


🐞 踩过的几个坑

虽然整体体验很好,但真用起来还是遇到几个坑,给大家踩过一遍,避免你也翻车:

动态类名无效

UnoCSS 是通过静态分析来生成类名的,像这种写法是不会生效的:

ts 复制代码
const size = 'lg'
return <div className={`text-${size}`}>文本</div>

解决方法是:

  • 静态写死可能的值;
  • 或配置 safelist 白名单:
ts 复制代码
safelist: ['text-sm', 'text-md', 'text-lg', 'text-xl']

IDE 无法提示类名

默认情况下 VSCode 不会自动提示 UnoCSS 类名,尤其是没有启用 attributify 的时候。 建议安装 UnoCSS 官方插件,并启用对应配置,能大幅提升开发效率。


📌 使用感受总结

经过这一轮实战,我对 UnoCSS 有了更完整的认识:

优点

  • 类名都是一眼能看懂的,看名字就知道样式;
  • 上手快,写一个类就能出效果;
  • 插件 preset 多,icons / shortcuts / web fonts 想用啥有啥;
  • 自定义能力强,几行代码搞定通用样式。

注意点

  • 动态类名需提前规划,避免运行时失效;
  • 公共样式建议封成 shortcuts;
  • 多人协作时需统一 className 命名习惯,不然易读性较差;

🤔 哪些场景适合用 UnoCSS?

  • 新项目从 0 起步,组件化程度高
  • 样式不重,但变化多,讲究效率的业务线
  • 团队能接受原子化类名这种写法

不太推荐的场景:

  • 老项目,已经铺了很多 SCSS 或 styled-components
  • 项目超重 UI,自定义样式太复杂
  • 团队成员完全没接触过原子化 CSS

✅ 最后总结

这次引入 UnoCSS 虽然只是新功能的一小步,但使用下来我真的觉得很爽:

  • 写得快;
  • 改得少;
  • 样式干净不乱;
  • 自定义很灵活。

跟 Tailwind 比,UnoCSS 更轻、更自由、更适合偏工程一点的团队。 如果你也在用 React + Vite,又想减少样式负担,真的可以试试看 UnoCSS。

如果你觉得这篇文章对你有帮助,欢迎点赞 👍、收藏 ⭐、评论 💬 让我知道你在看~ 我会持续更新 前端打怪笔记系列文章 ,👉 记得关注我,不错过每一篇干货更新!❤️

相关推荐
崔庆才丨静觅15 小时前
hCaptcha 验证码图像识别 API 对接教程
前端
passerby606116 小时前
完成前端时间处理的另一块版图
前端·github·web components
掘了16 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅16 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅16 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
崔庆才丨静觅17 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment17 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
崔庆才丨静觅17 小时前
刷屏全网的“nano-banana”API接入指南!0.1元/张量产高清创意图,开发者必藏
前端
剪刀石头布啊17 小时前
jwt介绍
前端
爱敲代码的小鱼17 小时前
AJAX(异步交互的技术来实现从服务端中获取数据):
前端·javascript·ajax