写在前面:当传统CSS遇上现代需求
"为什么我的页面在手机端显示错位?"、"用户深夜使用刺眼怎么办?"——这些前端开发高频痛点,本质上都是动态样式控制的命题。传统CSS面对响应式布局需要编写大量媒体查询,处理暗黑模式需要维护多套主题变量,而UnoCSS通过原子化思维和运行时动态生成能力,让这些需求变得像搭积木般简单。今天咱们就手把手实现这两个高频场景,看看如何用UnoCSS让样式代码既优雅又高效。
一、响应式布局的原子化革命
(1) 断点系统的本质解构
传统方案需要手动编写媒体查询:
/* 旧时代写法 */
@media (min-width: 768px) {
.container { padding: 2rem; }
}
在UnoCSS生态中,只需通过预设的断点前缀即可实现:
<!-- 现代原子化方案 -->
<template>
<div class="p-4 md:p-8 xl:p-12">
<!-- 移动端4单位padding,中屏8,大屏12 -->
</div>
</template>
/* 编译后的CSS */
.p-4 { padding: 1rem; }
@media (min-width: 768px) {
.md\:p-8 { padding: 2rem; }
}
@media (min-width: 1280px) {
.xl\:p-12 { padding: 3rem; }
}
技术原理:UnoCSS内置sm|md|lg|xl|2xl
五级断点系统(对应640|768|1024|1280|1536px),编译时自动生成带媒体查询的样式规则。
(2) 动态类名组合技巧
结合Vue3的响应式数据实现动态布局:
// 响应式栅格系统示例
const gridColumns = ref(1) // 默认1列
watch(() => window.innerWidth, (width) => {
gridColumns.value = width >= 1024 ? 3 : width >= 768 ? 2 : 1
})
<template>
<div :class="`grid grid-cols-${gridColumns} gap-4`">
<div v-for="n in 6" class="h-32 bg-blue-200 rounded-lg" />
</div>
</template>
/* 编译后的CSS */
.grid { display: grid; }
.gap-4 { gap: 1rem; }
.grid-cols-1 { grid-template-columns: repeat(1, minmax(0, 1fr)); }
.grid-cols-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.grid-cols-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.h-32 { height: 8rem; }
.bg-blue-200 { background-color: #bfdbfe; }
.rounded-lg { border-radius: 0.5rem; }
安全列表配置:
// uno.config.ts
export default defineConfig({
safelist: [
/^grid-cols-(1|2|3)$/, // 精确匹配动态生成的类名
]
})
二、暗黑模式的工程化实现
(1) 基础模式切换方案
通过Vue3的组合式API管理主题状态:
// useDark.ts
import { useDark, useToggle } from '@vueuse/core'
const isDark = useDark({
selector: 'html', // 作用在根元素
attribute: 'theme',
valueDark: 'dark',
valueLight: 'light'
})
const toggleDark = useToggle(isDark)
<!-- ThemeSwitch.vue -->
<template>
<button
@click="toggleDark()"
class="p-2 rounded-lg bg-gray-200 dark:bg-gray-700"
>
{{ isDark ? '🌙' : '☀️' }}
</button>
</template>
/* 编译后的CSS */
.p-2 { padding: 0.5rem; }
.rounded-lg { border-radius: 0.5rem; }
.bg-gray-200 { background-color: #e5e7eb; }
.dark .dark\:bg-gray-700 { background-color: #374151; }
实现效果:点击按钮时自动切换<html theme="dark">
属性,触发UnoCSS的暗黑模式类名。
(2) 深度定制暗黑主题
在uno.config.ts
中扩展自定义暗色方案:
// uno.config.ts
export default defineConfig({
theme: {
colors: {
primary: {
dark: '#5eead4', // 暗色系青绿色
DEFAULT: '#06b6d4'
}
}
},
darkMode: 'class' // 基于CSS类名切换
})
组件中使用语义化颜色类:
<template>
<div class="text-primary dark:text-primary-dark">
根据主题切换的文字颜色
</div>
</template>
/* 编译后的CSS */
.text-primary { color: #06b6d4; }
.dark .dark\:text-primary-dark { color: #5eead4; }
三、性能优化实践
(1) 按需生成验证与构建分析
通过构建分析查看输出结果:
npx unocss @src --out-file dist/uno.css
观察生成的CSS文件是否仅包含实际使用的样式规则,确保没有冗余代码。
推荐在vite配置中添加构建监听:
// vite.config.ts
export default defineConfig({
build: {
watch: {
include: ['src/**/*.vue', 'src/**/*.ts']
}
}
})
(2) 服务端渲染(SSR)适配增强
在Nuxt3中配置SSR兼容:
// nuxt.config.ts
export default defineNuxtConfig({
modules: ['@unocss/nuxt'],
unocss: {
preflight: true, // 注入默认样式
ssr: true, // 启用SSR支持
// 生产环境优化配置
mode: 'global',
combine: process.env.NODE_ENV === 'production'
}
})
(3) 图层管理与样式隔离
通过图层管理实现样式优先级控制:
// uno.config.ts
export default defineConfig({
layers: {
components: 10,
utilities: 20,
mylayer: 30
},
shortcuts: [
['btn', 'layer-mylayer px-4 py-2 rounded', { layer: 'mylayer' }]
]
})
(4) PurgeCSS深度集成
配置PurgeCSS实现二次清理:
// uno.config.ts
export default defineConfig({
postcss: {
plugins: {
'@unocss/postcss': {},
'postcss-purgecss': {
content: ['./src/**/*.vue'],
safelist: [/^grid-cols-\d+$/]
}
}
}
})
(5) 检查器工具使用
开发阶段启用检查器:
// vite.config.ts
export default defineConfig({
plugins: [
UnoCSS({
mode: 'global',
inspector: true // 启用浏览器检查器
})
]
})
访问localhost:5173/__unocss
可实时查看生成的样式规则
最后:让样式回归工程本质
通过本次分享实践可以看到,UnoCSS将响应式布局从媒体查询地狱简化为类名组合游戏,把暗黑模式从多套变量维护转化为语义化类名切换。这种原子化思维不仅提升了开发效率,更通过严格的按需生成机制保障了性能底线。
下次当你面对复杂样式需求时,不妨先思考:这个效果能否通过UnoCSS的原子类组合实现?