該系列已更新文章:
分享一個實用的 vite + vue3 組件庫腳手架工具,提升開發效率
開箱即用 yyg-cli 腳手架:快速創建 vue3 組件庫和vue3 全家桶專案
Vue3 企業級優雅實戰 - 組件庫框架 - 1 搭建 pnpm monorepo
Vue3 企業級優雅實戰 - 組件庫框架 - 2 初始化 workspace-root
Vue3 企業級優雅實戰 - 組件庫框架 - 3 搭建組件庫開發環境
在前一篇文章中分享了搭建組件庫的基本開發環境、創建了 foo 組件模塊和組件庫入口模塊,本文分享組件庫的樣式架構設計,
1 常見的 CSS 架構模式
常見的 CSS 架構模式有很多:OOCSS、ACSS、BEM、SMACSS、ITCSS 等,其中 SMACSS 和 ITCSS 很相似,我在企業級專案中最常使用的是簡化版的 ITCSS + BEM + ACSS,所以本文首先介紹這三種模式,其他模式大家自己上網查看,
1.1 ACSS
ACSS 模式幾乎是一個樣式屬性就對應了一個樣式類,這種方式非常靈活,復用性很強、維護成本低,但破壞了 CSS 命名語意化,常見的名稱如:d-flex、m-10、w-20 等,
1.2 BEM
BEM 模式是一種命名方法論,其命名層級為:塊 Block、元素 Element、修飾符 Modifier,這也是 “BEM” 這個名字的由來,元素 Element 使用兩個短下劃線(__),修飾符 Modifier 使用兩個短中劃線(--),如下面的 HTML 片段和對應的類名:
<div >
<a >Link</a>
<a >Link</a>
</div>
<style>
.demo-block {} // 塊
.demo-block__element1 {} // 元素
.demo-block__element1--modifier1 {} // 修飾符
</style>
使用 BEM 可以規范命令,頁面結構也比較清晰,
1.3 ITCSS
ITCSS 是一種樣式的分層結構,一共有七層,七個層次從上到下依次為:
- Settings 層:通常是一些樣式變數,如定義通用的顏色值、字體大小的數值等;
- Tools 層:通用工具函式,包括 mixins、function 等;
- Generic 層:通用基礎樣式,一般是對瀏覽器默認樣式進行重置,如 normalize.css、resets 等庫;
- Base 層:對某些全域使用的元素進行通用的定制化樣式,如頁面的設定、ul 標簽的設定等;
- Objects 層:所有使用 OOCSS 的地方,即某些結構和樣式相分離的專用類;
- Components 層:具體的組件,其實可以對應到組件庫中的每個組件;
- Trumps 層:重寫某些樣式,如 width 重新設定為 100px,只會影響某一小塊的 DOM 元素,權重最高,類似 ACSS,但通常會加上 !important,
2 組件庫的 CSS 架構
ITCSS 分層非常細致,咱們組件庫的樣式在其基礎上進行了簡化,省略了 Base 層 或 Objects 層,而對于 Trumps 層,咱使用 ACSS 來替代,對于 Components 層,里面的每個組件內部又使用 BEM,所以咱們組件庫的樣式架構為:簡化版的 ITCSS + BEM + ACSS,
2.1 CSS 結構概覽
組件庫的樣式使用前處理器 SCSS,從結構整體來看,分為如下層級:
- base 層:整個 CSS 結構的最基礎的層級,對應了 ITCSS 的 Settings、Generic 和 Base,即包括變數定義、通用基礎樣式和定制基礎樣式,
- tools 層:與 ITCSS 的 Tools 一樣,提供通用工具函式,
- acss 層:類似 ITCSS 的 Trumps,定義一些原子樣式類,如 flex、margin、padding 相關的樣式基礎類,
- components 層:與 ITCSS 的 Components 一樣,實作各個組件的樣式,其中每個組件的樣式又使用 BEM 方式來組織命名,
2.2 base 層的實作
前面說過,base 層包括樣式變數定義、通用基礎樣式、定制基礎樣式,
首先在 packages/scss 目錄下創建 base 目錄,存放 base 層的 scss 檔案,
- settings
settings 是一些變數的定義,在 packages/scss/base/ 目錄中創建 _var.module.scss 檔案,該檔案定義樣式變數,
$primary-color: #488019;
$common-padding: 20px;
:export {
primaryColor: $primary-color;
}
- Generic
Generic 通常是對瀏覽器樣式的重置,統一 HTML 標簽在不同瀏覽器中的展示,屏蔽瀏覽器間的差異,在這個部分可以使用開源庫normalize.css、reset.css 等,這一層可以在組件庫中省略,在各個具體的應用中引入對應css,不程序式員優雅哥還是將瀏覽器樣式重置引入到組件庫中,這樣應用開發程序中省點事,咱使用開源的 normalize.css 作為 Generic,normalize.css 的代碼可以在 GitHub 上搜索獲取,
繼續在 packages/scss/base/ 目錄中創建 _normalize.scss 檔案,將 normalize.css 的內容直接復制進去就可以了,
- Base
Base 主要是存放部分重置樣式的自定義,如 html、body、section 等,這部分咱們暫時沒有自定義的內容,就無需撰寫了,
- 入口檔案
最后需要將 base 層所有 scss 以統一的入口引入,在 packages/scss/base/ 目錄下創建 index.scss,該檔案匯入上面創建的兩個 scss 檔案:
@use "var.module";
@use "normalize";
2.3 tools 層的實作
tools 層用于存放工具函式和 mixins,github 上有個優秀的開源專案 sassMagic,咱們就使用它作為 tools 層,
將該專案 src 中的代碼拷貝到 packages/scss/tools/ 目錄下即可(如果 _sassMagic.scss 檔案中有報錯,將里面對不存在檔案的引入洗掉即可),我在這里將 _sassMagic.scss 檔案重命名為 index.scss,這樣后面在使用時只需要使用 @use "../tools" 即可,
2.4 acss 層的實作
acss 層用于定義一些原子樣式,這里咱們定義 flex 布局和 margin/padding 的原子類,
在 packages/scss/ 中創建目錄 acss,并在該目錄下創建兩個檔案:_flex.scss 和 _mp.scss,
packages/scss/acss/_flex.scss:
.f {
display: flex;
}
.f-c {
display: flex;
flex-direction: column;
}
.f-r {
display: flex;
flex-direction: row;
}
.f-1 {
flex: 1 1 0;
}
.oy-h {
overflow-y: hidden;
}
.oy-a {
overflow-y: auto !important;
}
.ox-h {
overflow-x: hidden;
}
.o-h {
overflow: hidden;
}
packages/scss/acss/_mp.scss:
$direction: (l left, r right, t top, b bottom);
@for $i from 1 through 30 {
@each $type in m, p, v, h, a {
// margin
@if ($type == m) {
@each $d in $direction {
.m#{nth($d, 1)}-#{$i} {
margin-#{nth($d, 2)}: #{$i}px;
}
}
}
// padding
@else if ($type == p) {
@each $d in $direction {
.p#{nth($d, 1)}-#{$i} {
padding-#{nth($d, 2)}: #{$i}px;
}
}
}
// margin/padding left/right
@else if ($type == h) {
.ph-#{$i} {
padding-left: #{$i}px;
padding-right: #{$i}px;
}
.mh-#{$i} {
margin-left: #{$i}px;
margin-right: #{$i}px;
}
}
// margin/padding top/bottom
@else if ($type == v) {
.mv-#{$i} {
margin-top: #{$i}px;
margin-bottom: #{$i}px;
}
.pv-#{$i} {
padding-top: #{$i}px;
padding-bottom: #{$i}px;
}
}
// all
@else {
.pa-#{$i} {
padding: #{$i}px;
}
}
}
}
2.5 components 層的實作
components 層對應組件庫中每個具體組件的樣式,在 packages/scss 中創建目錄 components,首先為上一篇文章中創建的 foo 組件創建樣式:在 packages/scss/components/ 目錄下創建 _foo.module.scss 檔案:
@import "../tools";
@import "../acss/mp";
@import "../base/var.module";
@include b('yyg-foo') {
color: $primary-color;
@include e('description') {
color: #333333;
@extend .mv-20;
}
}
繼續在 packages/scss/components/ 目錄下創建 index.scss 檔案,該檔案中引入 components 目錄下所有組件的 scss 檔案:
@use "foo.module";
如果新增了其他組件,需要在 components 目錄下創建該組件的樣式檔案,并在 components/index.scss 中引入該 scss 檔案,
2.6 樣式入口
在 packages/scss 下創建 index.scss,在里面匯入所有的 scss,使用組件庫時只需要引入該檔案即可,
@import "./acss/flex";
@import "./base";
@import "./components";
3 在組件庫中引入樣式
最后只需要在組件庫中引入 scss/index.scss 即可,在組件庫的入口模塊 packages/yyg-demo-ui/index.ts 中引入 index.scss:
import '../scss/index.scss'
(在上文中的代碼已經包括這一句引入了)
到此便完成了組件庫樣式架構的搭建,整個樣式的目錄結構如下:

感謝你閱讀本文,如果本文給了你一點點幫助或者啟發,還請三連支持一下,點贊、關注、收藏,程式員優雅哥會持續與大家分享更多干貨
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/533551.html
標籤:其他
