1. 为什么要在uniapp中使用unocss?
如果你正在使用uniapp开发跨平台应用,肯定遇到过样式管理的痛点。不同平台对CSS的支持程度不同,小程序有rpx单位,H5需要rem适配,还要考虑不同设备的响应式布局。传统CSS写法不仅繁琐,还容易产生冗余代码。
unocss就像是为uniapp量身定做的样式解决方案。它继承了Tailwind CSS的原子化理念,但更加轻量灵活。我在多个uniapp项目中实践后发现,使用unocss后开发效率提升了至少30%。特别是处理多平台适配时,再也不用写一堆@media查询和平台条件编译了。
举个例子,原来要实现一个按钮在不同平台的适配,你可能需要这样写:
/* 传统写法 */ .btn { padding: 10px 20px; border-radius: 4px; } /* 小程序专用 */ @media (min-width: 768px) { .btn { padding: 15rpx 30rpx; } }而用unocss只需要:
<button class="p-2 rounded">按钮</button>2. 环境准备与插件安装
2.1 创建uniapp项目
如果你还没有uniapp项目,建议使用Vite版本创建:
npm create uni-app@latest my-uniapp-project --template=vue3-ts进入项目目录后,先确保基础依赖安装完整:
cd my-uniapp-project && npm install2.2 安装unocss及相关插件
核心依赖包括三个部分:
npm install unocss @unocss/transformer-directives unocss-preset-weapp -D这里解释下每个包的作用:
unocss: 核心引擎@unocss/transformer-directives: 支持@apply等指令转换unocss-preset-weapp: 专门为小程序优化的预设
我在实际项目中发现,如果只用基础unocss,在小程序平台会遇到很多奇怪的问题。这个preset-weapp预设帮我们处理了小程序特有的样式限制,比如:
- rpx单位转换
- 避免使用不支持的CSS选择器
- 处理样式作用域问题
3. 配置文件详解
3.1 创建uno.config.ts
在项目根目录新建uno.config.ts,这是核心配置文件:
import presetWeapp from 'unocss-preset-weapp' import { extractorAttributify, transformerClass } from 'unocss-preset-weapp/transformer' import { defineConfig } from 'unocss/vite' import transformerDirectives from '@unocss/transformer-directives' const { presetWeappAttributify, transformerAttributify } = extractorAttributify() export default defineConfig({ presets: [ presetWeapp(), presetWeappAttributify() ], transformers: [ transformerDirectives({ enforce: 'pre' }), transformerAttributify(), transformerClass(), ], })这个配置有几个关键点需要注意:
presetWeappAttributify支持属性化写法,比如<div text-red>transformerDirectives要设置enforce: 'pre',这个后面会解释为什么transformerClass处理类名转换
3.2 配置vite.config.ts
虽然不直接影响unocss,但建议同步配置:
import { defineConfig } from 'vite' import uni from '@dcloudio/vite-plugin-uni' import UnoCSS from 'unocss/vite' export default defineConfig({ plugins: [ UnoCSS(), uni() ] })注意插件顺序很重要,UnoCSS()要在uni()之前注册。我在一个项目中因为顺序反了,导致样式完全不生效,排查了半天才发现这个问题。
4. 常见问题与解决方案
4.1 rpx转换失效问题
这是最常遇到的问题之一。当你在H5平台使用rpx单位时,发现没有自动转换为rem。这是因为uniapp和unocss的转换顺序冲突导致的。
解决方案就是在配置中给transformerDirectives加上enforce: 'pre':
transformers: [ transformerDirectives({ enforce: 'pre' }), // ...其他transformers ]原理是这样的:
- uniapp内部有自己的rpx转换插件
- unocss默认的transformers执行顺序在uniapp之后
- 设置
enforce: 'pre'让我们的转换先执行
4.2 样式作用域问题
在小程序中,组件样式默认是隔离的。如果你发现某些unocss生成的样式不生效,可能是作用域问题。
解决方法是在page.json中配置:
{ "styleIsolation": "shared" }或者在组件选项中设置:
export default { options: { styleIsolation: 'shared' } }4.3 生产环境样式丢失
有时候开发环境一切正常,但打包后样式丢失。这通常是因为PurgeCSS的配置问题。
在uno.config.ts中添加safelist:
export default defineConfig({ safelist: [ // 动态使用的类名 /^(bg|text|border)-.+$/, ] })我在一个电商项目中就遇到过这个问题,商品颜色是通过后端返回的class动态生成的,打包后所有颜色类都被PurgeCSS清理掉了。加上safelist正则后就解决了。
5. 开发技巧与最佳实践
5.1 自定义规则与预设
unocss的强大之处在于可以轻松扩展。比如我们要添加一些项目专用的工具类:
export default defineConfig({ rules: [ ['text-brand', { color: '#1a73e8' }], ['bg-brand', { 'background-color': '#1a73e8' }] ], shortcuts: { 'btn': 'py-2 px-4 rounded bg-brand text-white' } })5.2 多平台适配技巧
利用uniapp的条件编译和unocss的变体功能,可以优雅地处理平台差异:
<view class="h-10 sm:h-12 md:h-14"> <!-- 基础高度 --> </view> <view class="h-10 wx:h-12"> <!-- 微信小程序特殊高度 --> </view>5.3 性能优化建议
- 只引入需要的预设:
presets: [ presetWeapp({ // 只启用需要的功能 transform: true, whitelist: ['bg-brand'] }) ]- 开发时禁用缓存:
export default defineConfig({ mode: 'development', cache: false })- 生产构建时启用压缩:
export default defineConfig({ mode: 'production', minify: true })6. 实际项目案例
最近在一个跨平台教育类App中全面采用了unocss。项目需要同时支持微信小程序、H5和Android/iOS原生应用。通过unocss我们实现了:
- 样式代码量减少40%
- 多平台适配时间缩短60%
- 主题切换功能实现成本降低75%
具体实现方案:
// 主题配置 const themes = { light: { colors: { primary: '#3498db', secondary: '#2ecc71' } }, dark: { colors: { primary: '#2980b9', secondary: '#27ae60' } } } // unocss配置 export default defineConfig({ theme: { colors: themes.light.colors } })然后在应用中通过动态修改html的data-theme属性来切换主题。这种方式比传统的CSS变量方案更简洁,兼容性也更好。