封装element plus组件并用UnoCSS美化

前言

在日常的开发中，为了避免重复造轮子，浪费开发的时间，我们经常会使用到第三方组件库，如element plus、vant-ui等知名组件库，而在一些开发中往往为了项目的整体美观性，我们都不会直接拿着第三方组件库就直接拿来使用，会对其进行修改，使其更加贴合项目的整体 UI 风格，这个时候我们就可以将第三方组件库进行抽离，封装成公共组件库，而这种对第三方组件库进行封装的操作就被称为二次封装。

二次封装的好处

更遵守代码的简介之道✌️

便于项目后期的维护🤪

组件复用性更强🪄

Unocss 介绍

既然要对原第三方组件库进行封装，就难免对其样式进行修改，修改 css 往往是最让人头疼的 (起码对我来说是这样的🥹)，这时候我看见了antfu老师的重新构想原子化 CSS, 强烈建议先将这篇文章阅读后再看下去，会让你对原子化CSS有着更深的认识，这里用大神的话来概括一下就是:

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

而 Unocss 便是 antfu 老师做出的具有高性能且极具灵活性的即时原子化 CSS 引擎。至于为什么是引擎而不是一个 CSS 框架，是因为 Unocss 并没有提供任何的核心工具类，所有功能都可以通过预设和内联配置来提供

Unocss 的优势

灵活性 (属性化模式、上万个纯CSS图标、无需担心样式冲突)🪄

样式复用性强🐼

不用想类名！(这点对于起名困难的人来说帮助太大了)🤣

既然二次封装和Unocss都能够大大提高开发效率，让大家心情愉悦，那么接下来我们便试一试让这两件事情合在一起的样子，这里便拿element plus的loading加载组件进行简单的二次封装，再用Unocss来进行美化

二次封装的核心

这里是使用的vue3的组件封装方法，与vue2的封装方法还是有些许区别的，关于vue2的封装方法请看红尘老师的文章

$attrs

一个包含了组件所有透传 attributes 的对象。

这是 vue 官方对$attrs下的定义，是指由父组件传入，且没有被子组件声明为 props 或是组件自定义事件的 attributes 和事件处理函数。比如在组件当中我们用 标签嵌套了一个 的时候，想要让class或者v-on的监听器这类的透传 attribute 能直接应用在内部的 上，这时候我们就可以采用v-bind="$attrs"来实现

v-on 监听器继承

vue3当中直接删除了 2 里的$listeners事件监听器，现在直接将其功能融合到了$attrs中。例如写一个点击事件，在组件封装中，我们原子组件的点击，仍会触发父组件的 onclick 事件

Copy

click me

<MyButton @click="onClick" />

组件的封装

项目初始化

命令行输入:

Copy
pnpm create vite element-plus-unocss --template vue

使用vite+pnpm快速初始化项目

Copy
cd element-plus-unocss
pnpm i
pnpm run dev

成功运行后，项目的初始化便完成了

引入组件库

我们要封装的组件是element plus，故在此引入：

Copy
pnpm install element-plus

这里我们还是按照官方推荐的自动导入，这里就不多赘述了，直接附上了官网的链接，点击进行配置即可，接下来才是重点

二次封装

这里我们选择loading加载组件进行演示，在components中添加我们要封装的子组件loading.vue，直接复制官方的链接例子皆可 (可以适当做一点删减)：

Copy

<el-button
v-loading.fullscreen.lock="fullscreenLoading"
type="primary"
@click="openFullScreen1"
>
Click me
</el-button>



import { ref } from 'vue'
import { ElLoading } from 'element-plus'

const fullscreenLoading = ref(false)
const openFullScreen1 = () => {
fullscreenLoading.value = true
setTimeout(() => {
fullscreenLoading.value = false
}, 2000)
}


这时候我们再创建Myloading.vue组件，再在其中进行引入，并对其代码进行修改:

Copy

<Loading
v-bind="$attrs"
element-loading-text="正在努力加载~"
element-loading-background="rgba(122, 122, 122, 0.8)"
/>



import Loading from "./loading.vue";


.el-loading-mask .el-loading-spinner .el-loading-text {
font-size: 20px;
}


运行结果如下：

这时候便代表着我们组件的二次封装成功了

UnoCSS 美化组件

这个时候我们发现，似乎这个click me看上去死气沉沉的，完全没有让人点击的欲望，那么有什么方法可以让这个按钮给人一种呼之欲出，让人很想点击呢？这时候我们就可以请出我们的重量级人物UnoCSS了

安装并引入 UnoCss

Copy
pnpm i -D unocss

对vite.config.js进行配置：

Copy
import Unocss from 'unocss/vite'

export default {
plugins: [
Unocss({ /* options */ }),
],
}

并将UnoCSS引入到main.js中：import 'uno.css'

配置预设

配置预设是我认为UnoCSS的一个重要优势，只需要几个简单的预设，就能在几分钟搭建出属于自己的自定义框架，，属性化的特点就是 antfu 老师的Windi CSS的特点之一了，在UnoCSS中也将这一特点给保留了下来。这里我们就安装preset-attributify和unocss/preset-uno:

Copy
pnpm i -D @unocss/preset-attributify
pnpm i -D @unocss/preset-uno

修改后的vite.config.js：

Copy
import { defineConfig } from 'vite'
import AutoImport from 'unplugin-auto-import/vite'
import Components from 'unplugin-vue-components/vite'
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
import Unocss from '@unocss/vite'
import presetUno from '@unocss/preset-uno'
import presetAttributify from '@unocss/preset-attributify'

import vue from '@vitejs/plugin-vue'
export default defineConfig({
plugins: [vue(), AutoImport({
resolvers: [ElementPlusResolver()],
}),
Components({
resolvers: [ElementPlusResolver()],
}),
Unocss({
presets: [presetUno(), presetAttributify()]
})
]
})

此时我们便有了一个默认预设+属性模式的自定义框架了，之后写了一长串的 css 类后，就会直接按照属性模式进行分组，代码更加整洁，可读性大大加强：

Copy
<button
bg="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


修改组件的样式

我们为了让按钮看上去更有点击的欲望，我们可以尝试给click me加上一个跳跃的动画，这时候我们打开UnoCSS的playground，发现官方的演示里面就有着反复跳跃的样式，我们直接 cv 一下，修改我们的子组件:

Copy
<div class="
text-5xl
fw300
animate-bounce-alt
animate-count-infinite
animate-duration-1s"
>
click me


这时候我们感觉默认的按钮字体颜色似乎有些太深了，这时候我们再在父组件进行修改:

Copy
<Loading
element-loading-text="正在努力加载~"
v-bind="$attrs"
element-loading-background="rgba(122, 122, 122, 0.8)"
class="text-lg
fw300
m2
op70"
/>

这里如果我们想要知道 cv 的到底是什么内容，我们可以下载一个 UnoCSS 插件，直接在 vscode 中搜索即可，安装后再放在上面就会显示出这个类源码，便于后续的开发

好了，让我们来看看美化后的按钮的模样：

不停的跳动，是不是让人更有想要点击的欲望呢😂

结语

UnoCSS作为原子化 CSS 的新秀，让人眼前一亮，它吸取了前辈taiwind CSS的优势，融合了自己的windiCSS的特色，让它出奇的好用，尽管现在的它仍在测试版，但还是很推荐大家去尝试一下的，绝对会让你有种什么？还可以这样的感觉，还可以用UnoCSS来搭建一个属于你自己的组件库，这里贴一个自己的组件库项目，就是对 UnoCSS 的一次尝试:
https://github.com/isolcat/CatIsol-UI

组件库预览地址：https://cat-isol-ui.vercel.app😽