前言#
在日常的開發中,為了避免重複造輪子,浪費開發的時間,我們經常會使用到第三方組件庫,如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 和事件處理函數。比如在組件當中我們用<div>
標籤嵌套了一個<button>
的時候,想要讓class
或者v-on
的監聽器這類的透傳 attribute 能直接應用在內部的<button>
上,這時候我們就可以採用v-bind="$attrs"
來實現
v-on 監聽器繼承#
vue3
當中直接刪除了 2 裡的$listeners
事件監聽器,現在直接將其功能融合到了$attrs
中。例如寫一個點擊事件,在組件封裝中,我們原子組件的點擊,仍會觸發父組件的 onclick 事件
<!-- 子組件 -->
<button>click me</button>
<!-- 父組件 -->
<MyButton @click="onClick" />
組件的封裝#
專案初始化#
命令行輸入:
pnpm create vite element-plus-unocss --template vue
使用vite+pnpm
快速初始化專案
cd element-plus-unocss
pnpm i
pnpm run dev
成功運行後,專案的初始化便完成了
引入組件庫#
我們要封裝的組件是element plus
,故在此引入:
pnpm install element-plus
這裡我們還是按照官方推薦的自動導入,這裡就不多贅述了,直接附上了官網的鏈接,點擊進行配置即可,接下來才是重點
二次封裝#
這裡我們選擇loading
加載組件進行演示,在components
中添加我們要封裝的子組件loading.vue
,直接複製官方的鏈接例子皆可 (可以適當做一點刪減):
<template>
<el-button
v-loading.fullscreen.lock="fullscreenLoading"
type="primary"
@click="openFullScreen1"
>
Click me
</el-button>
</template>
<script lang="ts" setup>
import { ref } from 'vue'
import { ElLoading } from 'element-plus'
const fullscreenLoading = ref(false)
const openFullScreen1 = () => {
fullscreenLoading.value = true
setTimeout(() => {
fullscreenLoading.value = false
}, 2000)
}
</script>
這時候我們再創建Myloading.vue
組件,再在其中進行引入,並對其代碼進行修改:
<template>
<Loading
v-bind="$attrs"
element-loading-text="正在努力加載~"
element-loading-background="rgba(122, 122, 122, 0.8)"
/>
</template>
<script setup>
import Loading from "./loading.vue";
</script>
<style>
.el-loading-mask .el-loading-spinner .el-loading-text {
font-size: 20px;
}
</style>
運行結果如下:
這時候便代表著我們組件的二次封裝
成功了
UnoCSS 美化組件#
這個時候我們發現,似乎這個click me
看上去死氣沉沉的,完全沒有讓人點擊的欲望,那麼有什麼方法可以讓這個按鈕給人一種呼之欲出,讓人很想點擊呢?這時候我們就可以請出我們的重量級人物UnoCSS
了
安裝並引入 UnoCss#
pnpm i -D unocss
對vite.config.js
進行配置:
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
:
pnpm i -D @unocss/preset-attributify
pnpm i -D @unocss/preset-uno
修改後的vite.config.js
:
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 類後,就會直接按照屬性模式
進行分組,代碼更加整潔,可讀性大大加強:
<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
</button>
修改組件的樣式#
我們為了讓按鈕看上去更有點擊的欲望,我們可以嘗試給click me
加上一個跳躍的動畫,這時候我們打開UnoCSS
的playground
,發現官方的演示裡面就有著反復跳躍的樣式,我們直接 cv 一下,修改我們的子組件:
<div class="
text-5xl
fw300
animate-bounce-alt
animate-count-infinite
animate-duration-1s"
>
click me
</div>
這時候我們感覺默認的按鈕字體顏色似乎有些太深了,這時候我們再在父組件進行修改:
<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😽