Vue 3 与 UnoCSS 原子化 CSS

1. 核心概念与概述

1.1 UnoCSS 简介

UnoCSS 是一个具有高性能和灵活性的原子化 CSS 框架,它采用了即时编译(Just-In-Time)的方式,只生成实际使用到的 CSS。UnoCSS 设计理念是 "CSS on-demand",即按需生成 CSS,它支持多种预设,并允许开发者轻松扩展和自定义规则。

1.2 UnoCSS 主要特性

  • 高性能:即时编译,只生成使用到的 CSS
  • 灵活性:支持多种预设,可轻松扩展和自定义
  • 零配置:默认配置即可满足大多数需求
  • 丰富的预设:内置多种预设,如 Tailwind、Windi CSS、Bootstrap 等
  • 强大的变体系统:支持多种变体,如响应式、hover、focus 等
  • TypeScript 支持:提供类型安全的配置
  • Vite 原生集成:与 Vite 深度集成,提供最佳开发体验
  • 插件系统:支持通过插件扩展功能

1.3 Vue 3 与 UnoCSS 集成优势

  • 组件化设计:与 Vue 3 的组件化理念完美契合
  • 响应式数据:结合 Vue 3 的响应式系统,实现动态样式
  • 组合式 API:便于封装 UnoCSS 相关逻辑
  • TypeScript 支持:提供更好的类型安全性
  • 开发效率高:减少 CSS 文件数量,提高开发速度
  • 样式一致性:确保整个应用的样式统一
  • 高性能:UnoCSS 的即时编译机制带来卓越的性能

2. 核心知识与实现

2.1 Vue 3 项目中集成 UnoCSS

2.1.1 项目初始化

# 创建 Vue 3 项目
npm create vite@latest unocss-demo -- --template vue-ts
cd unocss-demo

# 安装 UnoCSS 依赖
npm install -D unocss

2.1.2 配置 UnoCSS

  1. vite.config.ts 中添加 UnoCSS 插件:
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()
  ],
})
  1. 创建 uno.config.ts 配置文件:
import { defineConfig } from 'unocss'

export default defineConfig({
  // 配置将在后续章节介绍
})
  1. main.ts 中导入 UnoCSS 样式:
import { createApp } from 'vue'
import './style.css'
import 'uno.css' // 导入 UnoCSS 样式
import App from './App.vue'

createApp(App).mount('#app')

2.1.3 基础用法示例

<template>
  <div class="container mx-auto p-4">
    <h1 class="text-3xl font-bold text-green-600 mb-4">
      UnoCSS 基础示例
    </h1>
    
    <div class="bg-white shadow-md rounded-lg p-6 mb-6">
      <h2 class="text-xl font-semibold mb-4">卡片标题</h2>
      <p class="text-gray-700 mb-4">
        这是一个使用 UnoCSS 样式的卡片组件,
        包含标题和描述文本。
      </p>
      <button class="bg-green-500 hover:bg-green-600 text-white font-medium py-2 px-4 rounded-md transition-colors">
        点击按钮
      </button>
    </div>
    
    <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
      <div class="bg-blue-50 border border-blue-200 rounded-lg p-4">
        <h3 class="font-semibold text-blue-800 mb-2">功能一</h3>
        <p class="text-blue-600">这是功能一的描述</p>
      </div>
      <div class="bg-green-50 border border-green-200 rounded-lg p-4">
        <h3 class="font-semibold text-green-800 mb-2">功能二</h3>
        <p class="text-green-600">这是功能二的描述</p>
      </div>
      <div class="bg-purple-50 border border-purple-200 rounded-lg p-4">
        <h3 class="font-semibold text-purple-800 mb-2">功能三</h3>
        <p class="text-purple-600">这是功能三的描述</p>
      </div>
    </div>
  </div>
</template>

2.2 UnoCSS 预设

UnoCSS 提供了多种预设,方便开发者快速开始使用。最常用的预设是 @unocss/preset-uno,它包含了类似 Tailwind CSS 的工具类。

2.2.1 安装和使用预设

npm install -D @unocss/preset-uno

uno.config.ts 中配置预设:

import { defineConfig } from 'unocss'
import presetUno from '@unocss/preset-uno'

export default defineConfig({
  presets: [
    presetUno()
  ]
})

2.2.2 常用预设

  • presetUno:类似 Tailwind CSS 的预设
  • presetAttributify:属性化模式预设
  • presetIcons:图标支持预设
  • presetTypography:排版预设
  • presetWebFonts:网络字体预设

2.3 属性化模式

UnoCSS 支持属性化模式,可以将原子化类作为 HTML 属性使用,使代码更简洁。

2.3.1 启用属性化模式

npm install -D @unocss/preset-attributify

uno.config.ts 中配置:

import { defineConfig } from 'unocss'
import presetUno from '@unocss/preset-uno'
import presetAttributify from '@unocss/preset-attributify'

export default defineConfig({
  presets: [
    presetUno(),
    presetAttributify()
  ]
})

2.3.2 使用属性化模式

<template>
  <div class="container mx-auto p-4">
    <h1 text="3xl bold green-600 mb-4">
      UnoCSS 属性化模式示例
    </h1>
    
    <div bg="white" shadow="md" rounded="lg" p="6" mb="6">
      <h2 text="xl semibold mb-4">卡片标题</h2>
      <p text="gray-700 mb-4">
        这是一个使用属性化模式的卡片组件。
      </p>
      <button 
        bg="green-500 hover:green-600" 
        text="white" 
        font="medium" 
        py="2" 
        px="4" 
        rounded="md" 
        transition="colors"
      >
        点击按钮
      </button>
    </div>
  </div>
</template>

2.4 图标支持

UnoCSS 提供了强大的图标支持,可以直接使用各种图标库。

2.4.1 安装和配置图标预设

npm install -D @unocss/preset-icons

uno.config.ts 中配置:

import { defineConfig } from 'unocss'
import presetUno from '@unocss/preset-uno'
import presetIcons from '@unocss/preset-icons'

export default defineConfig({
  presets: [
    presetUno(),
    presetIcons({
      prefix: 'i-', // 图标前缀
      extraProperties: {
        'display': 'inline-block',
        'vertical-align': 'middle'
      }
    })
  ]
})

2.4.2 使用图标

<template>
  <div class="container mx-auto p-4">
    <h1 class="text-3xl font-bold mb-6">UnoCSS 图标示例</h1>
    
    <div class="flex flex-wrap gap-4">
      <div class="bg-white shadow-md p-4 rounded-lg">
        <i class="i-carbon:home text-4xl text-green-500"></i>
        <p class="mt-2">主页图标</p>
      </div>
      
      <div class="bg-white shadow-md p-4 rounded-lg">
        <i class="i-carbon:user text-4xl text-blue-500"></i>
        <p class="mt-2">用户图标</p>
      </div>
      
      <div class="bg-white shadow-md p-4 rounded-lg">
        <i class="i-carbon:settings text-4xl text-purple-500"></i>
        <p class="mt-2">设置图标</p>
      </div>
      
      <div class="bg-white shadow-md p-4 rounded-lg">
        <i class="i-carbon:email text-4xl text-red-500"></i>
        <p class="mt-2">邮件图标</p>
      </div>
    </div>
  </div>
</template>

2.5 自定义规则

UnoCSS 允许开发者轻松自定义规则,扩展框架功能。

2.5.1 在 uno.config.ts 中添加自定义规则

import { defineConfig } from 'unocss'
import presetUno from '@unocss/preset-uno'

export default defineConfig({
  presets: [
    presetUno()
  ],
  rules: [
    // 自定义规则:bg-gradient-primary
    ['bg-gradient-primary', {
      background: 'linear-gradient(135deg, #42b983 0%, #35495e 100%)'
    }],
    
    // 自定义规则:text-shadow
    [/^text-shadow-(.*)$/, ([, shadow]) => {
      return {
        'text-shadow': shadow === 'sm' ? '1px 1px 2px rgba(0, 0, 0, 0.2)' : '2px 2px 4px rgba(0, 0, 0, 0.3)'
      }
    }],
    
    // 自定义规则:p-safe
    ['p-safe', {
      padding: 'env(safe-area-inset-top) env(safe-area-inset-right) env(safe-area-inset-bottom) env(safe-area-inset-left)'
    }]
  ]
})

2.5.2 使用自定义规则

<template>
  <div class="container mx-auto p-4">
    <h1 class="text-3xl font-bold mb-6">UnoCSS 自定义规则示例</h1>
    
    <div class="bg-gradient-primary text-white p-6 rounded-lg mb-4">
      <h2 class="text-2xl font-semibold mb-2 text-shadow-sm">渐变背景</h2>
      <p>这是一个使用自定义渐变背景规则的元素。</p>
    </div>
    
    <div class="bg-white shadow-md p-6 rounded-lg">
      <h2 class="text-2xl font-semibold mb-2 text-shadow-lg">文本阴影</h2>
      <p>这是一个使用自定义文本阴影规则的元素。</p>
    </div>
  </div>
</template>

2.6 变体系统

UnoCSS 提供了强大的变体系统,支持多种变体,如响应式、hover、focus 等。

2.6.1 内置变体

  • 响应式变体:sm:, md:, lg:, xl:, 2xl:
  • 状态变体:hover:, focus:, active:, visited:
  • 伪类变体:first:, last:, odd:, even:
  • 暗黑模式变体:dark:
  • 组合变体:md:hover:bg-blue-500

2.6.2 使用变体

<template>
  <div class="container mx-auto p-4">
    <h1 class="text-3xl font-bold mb-6">UnoCSS 变体示例</h1>
    
    <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
      <div class="bg-white shadow-md p-6 rounded-lg hover:shadow-lg transition-shadow">
        <h2 class="text-xl font-semibold mb-2">卡片 1</h2>
        <p>悬停时显示更大的阴影</p>
      </div>
      
      <div class="bg-white shadow-md p-6 rounded-lg">
        <h2 class="text-xl font-semibold mb-2">卡片 2</h2>
        <p>响应式宽度:sm:col-span-2 md:col-span-1</p>
      </div>
      
      <button class="bg-blue-500 hover:bg-blue-600 active:bg-blue-700 text-white font-medium py-2 px-4 rounded-md transition-colors">
        状态变体按钮
      </button>
      
      <button class="bg-green-500 hover:bg-green-600 focus:ring-2 focus:ring-green-300 text-white font-medium py-2 px-4 rounded-md transition-colors">
        焦点变体按钮
      </button>
    </div>
  </div>
</template>

3. 最佳实践

3.1 样式组织

  • 使用预设:根据项目需求选择合适的预设
  • 合理使用属性化模式:在适合的场景使用属性化模式,使代码更简洁
  • 自定义规则:将重复使用的样式组合为自定义规则
  • 使用变体:充分利用内置变体,减少自定义 CSS
  • 组织配置文件:将复杂的配置拆分为多个文件,提高可维护性

3.2 性能优化

  • 只导入必要的预设:避免导入不需要的预设
  • 合理使用变体:避免过度使用复杂变体
  • 优化图标使用:只使用实际需要的图标
  • 利用缓存:确保 UnoCSS 的缓存机制正常工作
  • 避免过度自定义:过度自定义会增加编译时间

3.3 开发体验

  • 使用编辑器插件:安装 UnoCSS 编辑器插件,提供自动补全和提示
  • 配置 TypeScript:启用 TypeScript 支持,获得更好的类型提示
  • 使用预设配置:利用社区提供的预设配置,加快开发速度
  • 文档化自定义规则:为自定义规则添加注释,便于团队协作
  • 定期更新:保持 UnoCSS 和相关插件的更新

3.4 响应式设计

  • 移动优先:先设计移动端样式,再逐步添加大屏幕样式
  • 合理使用断点:根据内容需求选择合适的断点
  • 测试不同设备:在实际设备上测试响应式效果
  • 考虑触摸目标:移动端按钮和交互元素尺寸至少为 48x48px

4. 常见问题与解决方案

4.1 样式不生效

问题:添加的 UnoCSS 类没有生成对应的样式
解决方案

  • 检查 vite.config.ts 中是否正确配置了 UnoCSS 插件
  • 检查 uno.config.ts 中是否启用了相应的预设
  • 确保在 main.ts 中导入了 uno.css
  • 检查类名是否拼写正确
  • 重启开发服务器

4.2 属性化模式不工作

问题:使用属性化模式时样式不生效
解决方案

  • 确保安装了 @unocss/preset-attributify
  • 检查 uno.config.ts 中是否配置了 presetAttributify
  • 检查属性名是否正确
  • 某些属性可能需要添加前缀,如 text- 前缀

4.3 图标不显示

问题:使用 presetIcons 时图标不显示
解决方案

  • 确保安装了相应的图标包
  • 检查 uno.config.ts 中是否正确配置了 presetIcons
  • 检查图标名是否拼写正确
  • 确保图标前缀配置正确

4.4 构建性能问题

问题:构建时间过长
解决方案

  • 只导入必要的预设和插件
  • 优化自定义规则,避免复杂的正则表达式
  • 检查 content 配置,只包含必要的文件
  • 考虑使用缓存机制

4.5 与其他 CSS 框架冲突

问题:UnoCSS 样式与其他 CSS 框架冲突
解决方案

  • 避免同时使用多个 CSS 框架
  • 使用 CSS Modules 或 Shadow DOM 隔离样式
  • 调整 UnoCSS 的优先级
  • 使用 layer 指令管理样式优先级

5. 进一步学习资源

5.1 官方文档

5.2 学习教程

5.3 开源项目

5.4 工具与资源

6. 代码优化与性能提升

6.1 优化配置文件

将复杂的配置拆分为多个文件,提高可维护性:

// uno.config.ts
import { defineConfig } from 'unocss'
import presetUno from '@unocss/preset-uno'
import presetAttributify from '@unocss/preset-attributify'
import { rules } from './unocss/rules'
import { shortcuts } from './unocss/shortcuts'

export default defineConfig({
  presets: [
    presetUno(),
    presetAttributify()
  ],
  rules,
  shortcuts
})
// unocss/rules.ts
export const rules = [
  // 自定义规则
  ['bg-gradient-primary', {
    background: 'linear-gradient(135deg, #42b983 0%, #35495e 100%)'
  }]
]
// unocss/shortcuts.ts
export const shortcuts = {
  'btn': 'px-4 py-2 rounded-md font-medium transition-colors',
  'btn-primary': 'bg-primary text-white hover:bg-primary/90',
  'card': 'bg-white shadow-md rounded-lg p-6 transition-shadow hover:shadow-lg'
}

6.2 使用快捷方式

使用 shortcuts 配置创建常用样式组合:

// uno.config.ts
import { defineConfig } from 'unocss'
import presetUno from '@unocss/preset-uno'

export default defineConfig({
  presets: [presetUno()],
  shortcuts: {
    'btn': 'px-4 py-2 rounded-md font-medium transition-colors',
    'btn-primary': 'bg-blue-500 text-white hover:bg-blue-600',
    'btn-secondary': 'bg-gray-200 text-gray-800 hover:bg-gray-300',
    'card': 'bg-white shadow-md rounded-lg p-6',
    'container': 'max-w-7xl mx-auto px-4 sm:px-6 lg:px-8'
  }
})

使用快捷方式:

<template>
  <div class="container">
    <h1 class="text-3xl font-bold mb-6">UnoCSS 快捷方式示例</h1>
    
    <div class="card mb-4">
      <h2 class="text-xl font-semibold mb-2">卡片标题</h2>
      <p class="mb-4">这是一个使用快捷方式的卡片</p>
      <div class="flex gap-2">
        <button class="btn btn-primary">主按钮</button>
        <button class="btn btn-secondary">次要按钮</button>
      </div>
    </div>
  </div>
</template>

6.3 启用 JIT 模式

UnoCSS 默认使用 JIT 模式,但可以进一步优化:

// uno.config.ts
import { defineConfig } from 'unocss'
import presetUno from '@unocss/preset-uno'

export default defineConfig({
  presets: [presetUno()],
  // 优化 JIT 编译
  jit: true,
  cache: true
})

6.4 配置内容扫描范围

优化 content 配置,只扫描必要的文件:

// uno.config.ts
import { defineConfig } from 'unocss'
import presetUno from '@unocss/preset-uno'

export default defineConfig({
  presets: [presetUno()],
  content: {
    pipeline: {
      include: [
        // 只扫描 Vue 文件
        /\.vue(\?.*)?$/,
        // 扫描 JavaScript/TypeScript 文件
        /\.[jt]sx?$/,
      ],
      exclude: [
        // 排除 node_modules
        /node_modules/,
        // 排除构建输出目录
        /dist/
      ]
    }
  }
})

7. 实践练习

7.1 基础练习:构建响应式卡片组件

  1. 创建一个 Vue 3 项目,集成 UnoCSS
  2. 配置 presetUnopresetAttributify
  3. 构建一个响应式卡片组件,包含标题、描述和按钮
  4. 使用属性化模式简化代码
  5. 添加悬停效果和过渡动画

7.2 进阶练习:构建导航栏组件

  1. 构建一个响应式导航栏组件
  2. 包含品牌 logo、导航链接和用户菜单
  3. 在移动端显示汉堡菜单
  4. 添加平滑的过渡动画
  5. 使用快捷方式简化样式

7.3 高级练习:构建仪表盘界面

  1. 构建一个完整的仪表盘界面
  2. 包含侧边栏导航、顶部导航、卡片网格和图表区域
  3. 使用自定义规则创建独特的样式
  4. 实现响应式设计,适配不同屏幕尺寸
  5. 添加深色模式支持

7.4 综合练习:构建电商产品页面

  1. 构建一个电商产品展示页面
  2. 包含产品图片画廊、产品信息、价格和购买按钮
  3. 实现产品变体选择(颜色、尺寸等)
  4. 添加购物车功能
  5. 确保良好的响应式设计和用户体验

8. 总结

UnoCSS 是一个强大的原子化 CSS 框架,与 Vue 3 结合使用可以显著提高开发效率和设计自由度。通过深度集成 UnoCSS,开发者可以构建出美观、响应式、高性能的 Vue 3 应用。

UnoCSS 的主要优势包括高性能、灵活性、零配置、丰富的预设和强大的变体系统。它支持多种预设,可以轻松扩展和自定义,与 Vite 深度集成,提供最佳的开发体验。

在实际项目中,需要根据具体需求选择合适的预设和配置,考虑样式组织、性能优化、开发体验等方面。同时,要注意保持良好的代码结构,使用快捷方式和自定义规则简化开发,充分利用 UnoCSS 的变体系统实现复杂的样式效果。

随着 UnoCSS 生态系统的不断发展,越来越多的工具和插件可供选择,掌握 Vue 3 与 UnoCSS 的深度集成将为开发者打开更多的可能性,无论是构建简单的单页应用还是复杂的企业级应用,都可以利用这项技术创造出令人惊叹的用户界面。

« 上一篇 Vue 3与Tailwind CSS深度集成 - 实用优先的样式解决方案 下一篇 » Vue 3与Storybook组件文档 - 组件开发与文档化全栈解决方案