第三章 使用UnoCSS原子化CSS
第三章 使用UnoCSS原子化CSS
原子样式也有很多选择,最著名的就是 Tailwind
。 Tailwind
虽然好,但是性能上有一些不足。由于Tailwind
会生成大量样式定义。全量的 CSS
文件往往体积会多至数 MB
。这个对于页面性能是完全不可接受的。如果在开发时进行动态的按需剪裁,又会影响编译性能,降低开发体验。为了解决性能问题,开源界一个叫做 Antfu
的大神设计了 UnoCSS
。UnoCSS
是一个拥有高性能且具灵活性的即时原子化 CSS
引擎,可以兼顾产物体积和开发性能。
本章任务
-
引入
UnoCSS
样式 -
实现组件属性定制按钮样式
-
实现【Icon图标按钮】
【task1
】引入UnoCSS
样式
- 安装依赖
pnpm i -D unocss@"0.45.6"
pnpm i -D @iconify-json/ic@"1.1.4"
其中的@iconify-json/ic
是字体图标库
- 在Vite配置文件中添加
UnoCSS
插件
文件名:vite.config.ts
import { presetUno, presetAttributify, presetIcons } from "unocss";
import Unocss from "unocss/vite";
export default defineConfig({
plugins: [
...
// 添加UnoCSS插件
Unocss({
presets: [presetUno(), presetAttributify(), presetIcons()],
})
],
});
下面就可以在插件中引入 UnoCSS
了。加载 Unocss
插件后,Vite
会通过分析 class
的使用状况提供相应的样式定义。
- 在
Button
组件中引入UnoCSS
文件名:src/button/index.tsx
注意: 这个地方文件名已经从
index.ts
变为index.tsx
import { defineComponent,PropType,toRefs} from "vue";
import "uno.css";
export default defineComponent({
name: "SButton",
setup(props, {slots}) {
return () => <button
class={`
py-2
px-4
font-semibold
rounded-lg
shadow-md
text-white
bg-green-500
hover:bg-green-700
border-none
cursor-pointer
`}
>
{slots.default ? slots.default() : ''}
</button>
}
});
- 在
index.ts
中添加一个测试代码
文件名: src/index.ts
import { createApp } from "vue";
import SmartyUI from "./entry"
createApp({
template:`
<div>
<SButton>普通按钮</SButton>
</div>
`
})
.use(SmartyUI)
.mount("#app");
- 启动项目
pnpm dev
- 在浏览器输入地址查看按钮组件
VITE v3.0.7 ready in 644 ms
➜ Local: http://localhost:5173/
➜ Network: use --host to expose
此时并没有看见页面出现按钮组件,且浏览器控制台抛出警告:
runtime-core.esm-bundler.js:38 [Vue warn]: Component provided template option but runtime compilation is not supported in this build of Vue. Configure your bundler to alias "vue" to "vue/dist/vue.esm-bundler.js".
at <App>
这个警告的意思是:组件提供 template
选项,但是在Vue
的这个构建中不支持运行时编译,在你的打包工具里配置别名“vue: vue/dist/vue.esm-bundler.js”
。
- 分析原因
项目的 vue/dist
目录下有很多不同的 Vue.js
构建版本,不同的环境使用不同的构建版本。使用构建工具的情况下,默认使用的是 vue.runtime.esm-bundler.js
这个仅运行时版本,不能处理 template
选项是字符串的情况,template
选项是字符串的情况要使用包含运行时编译器的版本 vue.esm-bundler.js
。
- 解决方案
在vite配置文件中配置别名resolve
。
文件名:vite.config.ts
export default defineConfig({
resolve: {
alias: {
vue: 'vue/dist/vue.esm-bundler.js',
},
},
plugins: [
...
// 插件
]
})
修改好别名后,保存就可以在浏览器看见一个绿色按钮了。
到此为止,说明 UnoCSS
已经正常引入了。
【task2
】实现组件属性定制按钮样式
根据属性定制按钮样式功能,就是可以修改组件的属性来达到你想要的目的,例如,通过color属性定制颜色。
<div>
<SButton color="blue">蓝色按钮</SButton>
<SButton color="green">绿色按钮</SButton>
<SButton color="gray">灰色按钮</SButton>
<SButton color="yellow">黄色按钮</SButton>
<SButton color="red">红色按钮</SButton>
</div>
- 定义属性类型并注册组件属性
文件名:src/button/index.tsx
import { defineComponent,PropType,toRefs} from "vue";
import "uno.css";
// 颜色类型声明
export type IColor = 'black' | 'gray' | 'red' | 'yellow' | 'green'|'blue'|'indigo'|'purple'|'pink'
export const props = {
color: {
type: String as PropType<IColor>,
default: 'blue' // 设定默认颜色
},
}
export default defineComponent({
name: "SButton",
props, // 注册属性
...
}
});
- 属性变量拼装
UnoCSS
文件名:src/button/index.tsx
export default defineComponent({
name: "SButton",
props,
setup(props, {slots}) {
return () => <button
class={`
py-2
px-4
font-semibold
rounded-lg
shadow-md
text-white
bg-${props.color}-500
hover:bg-${props.color}-700
border-none
cursor-pointer
m-1
`}
>
{slots.default ? slots.default() : ''}
</button>
}
});
- 修改
index.ts
文件,添加测试用例
文件名:src/index.ts
import { createApp } from "vue";
import SmartyUI from './entry'
createApp({
template:`
<div>
<SButton color="blue">蓝色按钮</SButton>
<SButton color="green">绿色按钮</SButton>
<SButton color="gray">灰色按钮</SButton>
<SButton color="yellow">黄色按钮</SButton>
<SButton color="red">红色按钮</SButton>
</div>
`
})
.use(SmartyUI)
.mount("#app");
- 启动项目
pnpm dev
- 在浏览器页面中查看
可以看到组件,但是但是灰色的,并没有看到我们给组件属性配置的颜色。这是为什么?
仔细研究 UnoCSS
的文档才发现问题。主要原因是 UnoCSS
默认是按需生成方式。也就是说只生成代码中使用过的样式。那如果在 class
属性中使用变量,是无法分析变量的取值的。这样也就无法动态生成样式了。
为了解决这个问题,UnoCSS
提供了安全列表选项。也就是说,把样式定义中变量的取值添加到 Safelist
中去。这样 UnoCSS
就会根据 Safelist
生成样式了。
- 开始定制安全列表
安全列表属性应该定义在 UnoCSS
插件的配置中。
这里面要做一个配置上的重构。考虑到后续会在 Safelist
中添加大量配置,所以我们将 UnoCSS
配置拆成一个新的 ts
模块,然后引用到 vite.config.ts
中。
项目在搭建的过程中会不断地进行重构。希望大家在开发的过程中,一定要积极思考如何编写更加合理易于维护的代码。
文件名:config/unocss.ts
import { presetUno, presetAttributify, presetIcons } from "unocss";
import Unocss from "unocss/vite";
const colors = [
"white",
"black",
"gray",
"red",
"yellow",
"green",
"blue",
"indigo",
"purple",
"pink",
];
const safelist = [
...colors.map((v) => `bg-${v}-500`),
...colors.map((v) => `hover:bg-${v}-700`),
];
export default () =>
Unocss({
safelist,
presets: [presetUno(), presetAttributify(), presetIcons()],
});
- 在
vite
配置中引入重构的unocss
配置
文件名:vite.config.ts
import Unocss from "./config/unocss";
export default defineConfig({
plugins: [
// 重构后的unocss配置
Unocss(),
],
})
- 重启项目
pnpm dev
- 在浏览器查看结果
此时可以看到组件,以及我们想要的对应的组件属性所配置的颜色了。
【task3
】Icon 图标按钮实现
接下来要给按钮增加图标定制功能。实现图标按钮,首先需要引入字体图标库。
在 UnoCSS
中引入图标,只需要加载 @unocss/preset-icons
预设就可以了。它提供了 iconify
图标框架中大量的图表集。
- 开始引入这个功能,首先在
Unocss
插件中添加presetIcons
预设。
文件名: config/unocss.ts
export default () =>
Unocss({
safelist,
presets: [
presetUno(),
presetAttributify(),
presetIcons(), // 添加图标预设
]
});
- 定制图标安全列表
为了能够在 UnoCSS
中使用变量定义字体图标,需要将使用的图标名加入到 safelist
中。
文件名:config/unocss.ts
const safelist = [
...[
"search",
"edit",
"check",
"message",
"star-off",
"delete",
"add",
"share",
].map((v) => `i-ic-baseline-${v}`),
];
- 在
Button
组件中注册icon
属性
文件名:src/button/index.tsx
export const props = {
icon: { // 注册icon属性
type: String,
default: ''
}
}
- 在
Button
组件 中添加字体图标
文件名:src/button/index.tsx
return () => <button
class={`
...
mx-1
`}
>
{ props.icon !== "" ? <i class={`i-ic-baseline-${props.icon} p-3`}></i> : ""}
{slots.default ? slots.default() : ''}
</button>
- 在
index.ts
中添加测试用例
文件名:src/index.ts
import { createApp } from 'vue'
import SmartyUI from './entry'
createApp({
template: `
<div style="margin-top:20px;">
<SButton color="blue" icon="search" ></SButton>
<SButton color="green" icon="edit"></SButton>
<SButton color="gray" icon="check"></SButton>
<SButton color="yellow" icon="message"></SButton>
<SButton color="red" icon="delete"></SButton>
</div>
`,
本篇文章来至:学新通
- 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
- 本站站名: 学新通
- 本文地址: https://www.swvq.com/boutique/detail/tanhcikcji
- 联系方式: luke.wu#vfv.cc
-
《学习通》视频自动暂停处理方法
HelloWorld317 07-05 -
photoshop保存的图片太大微信发不了怎么办
PHP中文网 06-15 -
excel下拉菜单选择后怎么自动出现相应内容
PHP中文网 06-24 -
excel下划线不显示怎么办
PHP中文网 06-23 -
微信公众号没有声音提示怎么办
PHP中文网 03-31 -
wphotoshop工具右键快捷工具不见了怎么办
PHP中文网 06-19 -
微信小程序没声音怎么办
PHP中文网 06-15 -
手机怎样打开html文件
PHP中文网 05-20 -
把文字添加蓝色阴影边框
PHP中文网 06-28 -
pr编辑工具栏面板不见了怎么办
PHP中文网 05-09