欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 文旅 > 游戏 > 27 Vue3之unocss原子化

27 Vue3之unocss原子化

2024/10/25 5:23:57 来源:https://blog.csdn.net/qq_37550440/article/details/142637345  浏览:    关键词:27 Vue3之unocss原子化

前置知识

什么是原子化 CSS

原子化 CSS 是一种 CSS 的架构方式,它倾向于小巧且用途单一的 class,并且会以视觉效果进行命名。

 为什么使用 原子化 CSS

传统方案

制作原子化 CSS 的传统方案其实就是提供所有你可能需要用到的 CSS 工具。例如,你可能会用预处理器(这里选用的是 SCSS)生成如下代码:

// style.scss@for $i from 1 through 10 {.m-#{$i} {margin: $i / 4 rem;}
}

编译结果为:

.m-1 { margin: 0.25 rem; }
.m-2 { margin: 0.5 rem; }
/* ... */
.m-10 { margin: 2.5 rem; }

现在你可以直接使用 class="m-1" 来设置边距。但正如你所见,用这种方法的情况下,你不能使用除了 1 到 10 之外的边距,而且,即使你只使用了其中一条 CSS 规则,但还是要为其余几条规则的文件体积买单。如果之后你还想支持不同的 margin 方向,使用比如 mt 代表 margin-topmb 代表 margin-bottom 等,加上这 4 个方向以后,你的 CSS 大小会变成原来的 5 倍。如果再有使用到像 :hover 和 :focus 这样的伪类时,体积还会得更变大。以此类推,每多加一个工具类,往往意味着你 CSS 文件的大小也会随之增加。这也就是为什么传统的 Tailwind 生成的 CSS 文件会有数 MB 的大小。

为了解决这个问题,Tailwind 通过使用 PurgeCSS 来扫描你的打包产物并删除你不需要的规则。这得以使其在生产环境中 CSS 文件缩减为几 KB。然而,请注意,这个清除操作仅在生成构建下有效,而开发环境下仍要使用包含了所有规则巨大的 CSS 文件。这在 Webpack 中表现可能并不明显(项目过大也会有着巨大影响),但在 Vite 中却有着巨大的影响,毕竟其他内容的加载都非常迅捷。

Tailwind对比unocss

例如,我们知道 Tailwind 中的 border-2 标识边框宽度为 2px4 表示 4px6 表示 6px8 表示 8px,但当你使用 border-10 却不起作用你甚至需要一些时间来发现这件事!)。你可能会说这是故意而为之,以使得设计系统具有一致性。不如这样,我们来做个小测验,如果想要让 border-10 正常工作,应该如何做?

在你的全局样式中的某个位置添加这样一个工具类?

.border-10 {border-width: 10px;
}

快速且直观,最重要的是,它的确解决了你的需求。但是,如果什么都需要我自己手动添加,那我们为什么还需要使用 Tailwind ?

可参考文章

重新构想原子化 CSS

UnoCSS官方中文文档  指南

自 2023 年 3 月起不再积极维护windicss官方文档 Getting Started | Windi CSS


 

使用unocss 

在vscode编辑器中安装unocss插件 能友好的提示

npm i -D unocss 

vite.config.ts 

import unocss from 'unocss/vite'plugins: [vue(), vueJsx(),unocss({rules:[
//配置自定义规则 ['U-flex', { display: "flex" }]]})],

main.ts 引入

import 'uno.css'

1 配置自定义规则

rules: [['flex', { display: "flex" }]
]
<template><divclass="u-flex">什么是原子化CSS</div>
</template><script setup lang="ts">
import { ref, reactive } from "vue";
</script><style lang="less" scoped></style>

 效果图:

2 配置动态css(使用正则表达式)

m-参数   例如 m-10 就是 margin:10px

rules: [[/^m-(\d+)$/, ([, d]) => ({ margin: `${Number(d) * 10}px` })],['flex', { display: "flex" }]
]

 3 .shortcuts 可以自定义组合样式

  plugins: [vue(), vueJsx(), unocss({rules: [['pink', { color: 'pink' }]],shortcuts: {btn: "pink flex"}})],

4 unocss 预设

 presets:[presetIcons(),presetAttributify(),presetUno()]
4.1.presetIcons Icon图标预设

图标集合安装

npm i -D @iconify-json/ic

首先我们去icones官网(方便浏览和使用iconify)浏览我们需要的icon,比如这里我用到了Google Material Icons图标集里面的baseline-add-circle图标 

比如你想使用Element Plus的图标库 直接查询后能看到网址https://icones.js.org/collection/ep

能看到是/ep结尾的 下载命令就是

npm i -D @iconify-json/ep

 不加/ep就是下载所有的图标库体积会特别大

4.2.presetAttributify 属性化模式支持

属性语义化 无须class

vite.config.ts 


import { defineConfig, presetAttributify, presetUno } from 'unocss'export default defineConfig({presets: [presetAttributify({ /* preset 选项 */}),presetUno(),// ...自定义 presets],
rules:[]
})
<div font="black">btn</div><buttonclass="bg-blue-400 hover:bg-blue-500 text-sm text-white font-mono font-light py-2 px-4 rounded border-2 border-blue-200 dark:bg-blue-500 dark:hover:bg-blue-600">未使用属性化模式支持 css Button</button><buttonbg="blue-400 hover:blue-500 dark:blue-500 dark:hover:blue-600"text="sm white"font="mono light"p="y-2 x-4"border="2 rounded blue-200">使用属性化模式支持Button</button><div w20 h20 bg-blue-500>使用属性化模式支持Button 省略class后无类名提示。。。</div>
4.3.presetUno 工具类预设

tips:默认的预设是基于Windi CSS的注意margin 和border的单位是px,其他样式是rem

默认的 @unocss/preset-uno 预设是一系列流行的原子化框架的 通用超集,包括 Tailwind CSS、Windi CSS、Bootstrap、Tachyons 等。

例如,ml-3(Tailwind CSS)、ms-2(Bootstrap)、ma4(Tachyons)和 mt-10px(Windi CSS)都是有效的。

.ma4 { margin: 1rem; }
.ml-3 { margin-left: 0.75rem; }
.ms-2 { margin-inline-start: 0.5rem; }
.mt-10px { margin-top: 10px; }
4.4 Rem to px 预设​

将所有工具类中的 rem 转换为 px。

pnpm add -D @unocss/preset-rem-to-px

// uno.config.ts
import { defineConfig } from 'unocss'
import presetRemToPx from '@unocss/preset-rem-to-px'export default defineConfig({presets: [presetRemToPx(),// ...other presets],
})

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com