UnoCSS 的官网首页,已经为我们展示了它的优点

  1. 没有核心实用程序。所有功能均通过预设提供。
  2. 瞬间。无需解析、无需 AST、无需扫描。它比 Windi CSS 或 TailWind JIT 快 5 倍。
  3. 轻量级。零 deps 和浏览器友好:~6kb min+brotli。
  4. 丰富的集成。一流的 Vite、Webpack、PostCSS、CLI、VS Code、ESLint 等支持。
  5. 快捷方式。动态地对实用工具进行别名或分组。
  6. 属性模式。将实用工具分组放置在属性中。
  7. 纯 CSS 图标。使用单个类名作为任意图标。
  8. 变体组。使用常见前缀的快捷方式来组合实用工具。
  9. CSS 指令。使用 @apply 指令在 CSS 中重用实用工具。
  10. 编译模式。在构建时将多个类合成为一个类。
  11. 检查器。交互式地进行检查和调试。
  12. CDN 运行时构建。使用一行 CDN 引入代码即可使用 UnoCSS。

如上已经说的很全面了,UnoCSS 的设计理念是简洁易用,提供了一套直观和易于记忆的类名,使得开发人员能够快速编写和理解样式代码。它遵循类似于 Tailwind CSS 的风格,使用直观的命名规则来描述样式的作用。而且 Antfu 大佬也是 Tailwind 的作者之一。

# UnoCSS 是什么?

# CSS 原子化

在前端开发中, CSS原子化 (Atomic CSS)是一种设计和编写 CSS 样式的方法论。它的核心思想是将样式属性拆分为独立的、可重用的类名,每个类名仅定义一个样式属性。

# 优点

原子化 CSS 的好处之一是提供了高度的可重用性。通过将样式属性拆分为独立的类名,我们可以根据需要组合这些类名来构建所需的样式。这种模块化的方法使得样式的管理和维护更加简单,也更容易实现样式的复用。例如,如果我们有一个名为 .text-center 的类,它定义了文本居中对齐的样式,我们可以在需要时将其应用于任何元素。

原子化 CSS 还有助于减小样式表的大小。由于每个类名只定义一个样式属性,因此样式表中的类名数量相对较多,但每个类名的定义相对较短。这可以帮助减小样式表的大小,从而加快加载时间和提升性能。

另一个原子化 CSS 的优势是可预测性。由于每个类名只定义一个样式属性,类名与样式的关联非常明确。这使得在查看 HTML 元素的类名时,可以直观地了解它们应用的样式。这也使得在不破坏其他样式的情况下,可以更方便地添加或移除特定样式

# 缺点

原子化 CSS 并不适用于所有情况。在某些情况下,它可能会导致样式的冗余和维护的困难。如果我们有大量的独立样式属性需要定义,使用原子化 CSS 可能会导致类名数量爆炸,并且难以管理。因此,在使用原子化 CSS 时,需要在可重用性和可维护性之间做出权衡,并根据具体情况做出决策。

本文教程最终效果,结尾又源码

img

# 初始化项目

当然首先确保已经安装了 Node,并且按照目前 Vite 需要的 Node 版本,Vite 不再支持 Node 12 / 13 / 15,因为上述版本已经进入了 EOL 阶段。现在你必须使用 Node 14.18+ / 16+ 版本。有了环境,就要开始写代码了~

使用 tdesign-starter-cli 初始化一个 Vue3 项目

安装 tdesign-starter-cli

npm i tdesign-starter-cli -g

创建项目

td-starter init

随后在终端会有一些选项

img

安装依赖

# 进入项目
cd ./Vue3-Vite4-Tdesign-UnoCSS
# 安装依赖
npm install
# 运行
npm run dev

img

# 使用 UnoCss

安装依赖

接下来进入 Vscode,添加对 UnoCss 的支持。

pnpm add -D unocss
// or
yarn add -D unocss
// or
npm install -D unocss

# 创建配置文件

在项目根目录下修改 vite.config.js 文件,添加 UnoCSS 插件到 Vite 中。

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import UnoCSS from 'unocss/vite'
// https://vitejs.dev/config/
export default defineConfig({
  plugins: [vue(),UnoCSS()],
})

在项目根目录下创建 uno.config.js 文件。写入以下内容

更多配置可以参考官网

// uno.config.js
import { defineConfig, presetUno } from 'unocss'
export default defineConfig({
  presets: [
    presetUno(), // 添加 UnoCSS 的默认样式预设
  ],
})

App.vue 中写入以下内容进行测试是否安装 UnoCSS 并能够成功使用

<script setup>
</script>
<template>
  <div class="text-color-red">
    Hello World!
  </div>
</template>

main.js 入口文件写入以下内容

import { createApp } from 'vue'
import './style.css'
import App from './App.vue'
import 'virtual:uno.css'
createApp(App).mount('#app')

随后 pnpm run dev 启动项目,在控制台打开 http://127.0.0.1:5173 即可查看成功使用了 UnoCSS 的样式页面。

官方还给开了个后门,打开 http://localhost:5173/__unocss#/ ,即可查看具体样式编译后的文件

img

# 查找样式规则

UnoCss 提供了很多样式规则,我们又没办法都记住,作者很友好的提供了一个样式规则互动工具(unocss.dev/interactive)。

支持多种查询方式。

img

class 查找

img

样式查找

# 预设样式规则

如果以为他只能做这些就打错特错了,他还支持在默认预设样式基础上添加预设。

还可以通过 shortcuts 定义组合样式

import { defineConfig, presetUno } from 'unocss'
const handlerColorOrSize = (d, prefix) => {
    const defaultCode = 7;
    const colorArr = ['brand', 'gray', 'success', 'error', 'warning'];
    const color = d.match(/([^-]+)/)[1];
    let num = defaultCode;
    const regularNum = d.match(/-(\d+)/);
    if (regularNum) {
        num = Math.floor(Number(regularNum[1]));
    }
    if (Number(num) < 11 && Number(num) > 0 && colorArr.includes(color)) {
        return Array.isArray(prefix)
            ? Object.fromEntries(prefix.map((key) => [key, `var(--td-${color}-color-${num})`]))
            : { [prefix]: `var(--td-${color}-color-${num})` };
    }
    return {};
};
export default defineConfig({
  presets: [
    presetUno(), // 添加 UnoCSS 的默认样式预设
    /**
     * @description: 颜色
     * @return border-color
     * @class ('border' | 'b')-color?-('brand' | 'gray' | 'success' | 'error' | 'warning')-(10 以内数字)?
     * 例如  border-color-success  |  b-color-success |  border-brand  |  b-color-brand |  b-color-gray-10
     */
    
    // 自定义预设
    {
        name: 'unocss-tdesign-class',
        // 定义实用程序规则
        rules: [
            [
                /^(?:border|b)-()(?:color-)?(.+)$/,
                ([,,b]) => handlerColorOrSize(b, 'border-color'),
                { autocomplete: 'bg-$colors' },
            ]
        ],
        // 定义组合样式
        shortcuts: {
          'my-border': 'b-color-brand b-b-5 b-b-dotted',
        },
      },
  ],
})

经验分享

预设样式可以使用正则进行匹配,使用正则推荐用 regex101 可以让你少走很多弯路。

img

当然如果没有网也可以用浏览器写示例验证。

img

const regex = /^(?:border|b)-()(?:width|size)-(.+)$/;
const handleMatch = ([, a = '', b]) => {
  console.log('a',a)
  console.log('b',b)
}
const inputString = 'border-width-0';
const match = inputString.match(regex);
if (match) {
  handleMatch(match);
} else {
  console.log('没有匹配.');
}

# VScode UnoCss 插件

UnoCSS - Visual Studio Marketplacemarketplace.visualstudio.com/items?itemName=antfu.unocss

img

# 插件不生效问题

为了获得最佳的 IDE 体验,我们建议您 ef="https://un ocss.dev/guide/config-file"> 使用单独的 uno.config.ts 文件来配置 UnoCSS。

该扩展将尝试在您的项目下查找 UnoCSS 配置。当未找到配置时,该扩展将被禁用。要使用 monorepo,您需要将 中的选项更改为包含配置文件的目录。

"unocss.root": [
  "E:/myGit/Vue3-Vite4-Tdesign-UnoCSS/",
],

# 总结

很多人可能根本没使用过原子化 CSS,我也是最近写一个新的项目了解到这个概念所以想尝试一下,结果发现确实还挺有意思的。例如像 Tailwind Css,在大部分以 Vue 为基础框架的项目中,其实都会安装类似 Element UI 或者 Ant Design 的 UI 框架,在 template 中直接把 UI 框架封装好的组件拿过来用就好了,真正写 css 的地方可能比较少,但是也不一定。这个时候去使用 UnoCSS,把 div 和 css 绑定到一起,见名知意。有点像把样式写到 style 里面一样,其实是很方便的。例如常见的写一个 flex 布局给某一个 div 。

<div class="flex flex-row flex-justify-center flex-items-center">xxx</div>

会被翻译

.flex {
  display: flex;
}
.flex-row {
  flex-direction: row;
}
.flex-justify-center {
  justify-content: center;
}
.flex-items-center {
  align-items: center;
}

上面所说的只是 UnoCS 的最基础的功能。在上面介绍到的优点中,例如 纯CSS图标CSS 指令 等也是非常实用且方便的技巧。