日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > HTML >内容正文

HTML

封装html ui 控件,聊聊前端 UI 组件:组件设计

發布時間:2025/3/12 HTML 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 封装html ui 控件,聊聊前端 UI 组件:组件设计 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

本文首發于歐雷流。由于我會時不時對文章進行補充、修正和潤色,為了保證所看到的是最新版本,請閱讀原文。

在本系列文章《聊聊前端 UI 組件:組件體系》中初步說明了 UI 組件的架構設計,本文將在此基礎上進一步展開說說那篇文章中一筆帶過的部分,并闡述在設計一個 UI 組件時應該注意的點有哪些。

目錄結構

在《聊聊前端 UI 組件:組件體系》中列出的目錄結構的基礎上做了些許調整——component

├── demo # 示例相關文件

│ └── ...

├── test # 測試相關文件

│ └── ...

├── style # 樣式相關文件

│ ├── _functions.scss # Sass 函數(可選)

│ ├── _properties.scss # CSS 自定義屬性(必需),風格組件的一部分,供外部運行時自定義主題風格

│ ├── _variables.scss # Sass 變量(必需),風格組件的一部分,供外部編輯時/編譯時自定義主題風格

│ ├── _mixins.scss # Sass 混入(可選)

│ └── _rules.scss # CSS 規則(必需),視覺組件,具有約束結構的作用

├── typing # 類型相關文件

│ ├── custom-properties.ts # CSS 自定義屬性配置項(必需),用于運行時生成 CSS 自定義屬性

│ ├── aliases.ts # 類型別名(可選)

│ ├── interfaces.ts # 結構組件接口(必需)

│ └── index.ts # 類型統一導出

├── HeadlessComponent.ts # 無頭組件,UI 組件與結構無關的邏輯

├── Component.vue # 結構組件,受生成 HTML 的 JS 庫/框架的源碼、平臺限定的視圖結構描述語言影響

├── index.ts # 模塊統一導出

├── changelog.md # 組件變更記錄

├── readme.md # 組件說明文檔

├── metadata.yml

└── package.json

命名約定

HTML & CSS class

在基于組件開發(Component-based Development),即大家所說的「組件化」,在 web 前端領域普及之前,流行過一種神奇的 class 命名方式,可以說是一種方法論了——原子類(atomic classes)。

估計一入行就是 React、Vue 橫行的前端,壓根兒就沒聽過更沒見過「原子類」是個什么東西——

.w-100 { width: 100px; }

.w-150 { width: 150px; }

.h-100 { height: 100px; }

.h-150 { height: 150px; }

.m-10 { margin: 10px; }

.m-20 { margin: 20px; }

.mt-10 { margin-top: 10px; }

.ml-15 { margin-left: 15px; }

.bgc-red { background-color: red; }

.bgc-greed { background-color: green; }

.c-fff { color: #fff; }

.c-000 { color: #000; }

.f-l { float: left; }

.f-r { float: right; }

Atomic classes

看到了吧,這種方法論強調的就是盡可能將 CSS 的每個屬性和值的組合拆成 class,命名方式也基本是「屬性名 + 屬性值」的形式,并且屬性名和屬性值是否進行「簡寫」以及中間有沒有 -、_ 等分隔符就看編寫的人的素養和心情了。

原子類的「優點」是,它把 class 拆分到足夠細,很好很「原子」;原子化帶來的特點就是可組合性很強,這樣任何頁面都可以通過原子類的有機組合去實現,只有想不到,沒有做不到!哪天設計師說要把按鈕距離左邊的 15 像素改為 10 像素——沒問題!把 的 .ml-15 換成 .ml-10 就好!小菜一碟!

為什么上面說的「優點」是加了引號的?我就想知道,原子類除了寫的時候字符數可能會稍微少些,跟寫內聯樣式(inline style)有什么區別?有更語義化嗎?可讀性有變更好嗎?人腦負擔有降低嗎?中、大型項目維護起來更方便嗎?

隨著基于組件開發在 web 前端領域的普及,原子類的身影逐漸消失;但最近因為某個 CSS 框架人氣走高的原因,原子類再度死灰復燃……

那么,原子類或者說樣式原子化是錯的嗎?不是,都是時臣的錯!啊,不!都是 utility-first 思想的錯!

class 應該是語義化的,尤其是在基于組件開發時,讓在視圖結構中一眼看到 class 后,就知道它是個什么東西,而不是它長什么樣。

另外,基于組件開發的特點之一就是封裝,對外屏蔽內部細節;而 utility-first 思想恰恰是暴露細節,這與基于組件開發的理念「三觀不合」。

在基于組件開發的體系下,class 理應是 component-first,即應用 CSS 組件(CSS component),那些 utility class 作為輔助存在。也就是說,當 CSS 組件自帶樣式與實際需求有些許不符時,利用 utility class 進行「微調」,而不是在外部重寫 CSS 組件的樣式——這也是一種組合方式。

比如,按鈕 CSS 組件本身是不會在水平方向撐滿容器的,但設計師想讓它占滿一行——

.Button {

display: inline-block;

text-align: center;

}

.u-block {

display: block !important;

}

CSS component

CSS 組件在本系列文章所闡述的 UI 組件體系中,叫做「視覺組件」,class 的命名遵循 BEM 的變體——SUIT CSS 命名約定。

SUIT CSS 是 Normalize.css 的作者 Nicolas Gallagher 于 2013 年左右時創立,雖然現在已經處于基本不維護的狀態了,但它基于組件開發的思想仍發揮著余熱。

SUIT CSS 命名約定我從 2014 年用到現在,并且會繼續用下去。本系列文章 CSS 相關的示例代碼中 class 的命名皆遵循此命名約定。在基于組件開發的體系下,強烈建議 class 命名遵循 SUIT CSS 命名約定——/* 組件 */

.ComponentName {}

/* 組件修飾符 */

.ComponentName--modifierName {}

/* 組件后代 */

.ComponentName-descendentName {}

/* 組件狀態 */

.ComponentName.is-stateOfComponent {}

/* 輔助工具 */

.u-utilityName {}

組件基類 .ComponentName 及其后代 .ComponentName-descendentName 很好理解,它們天然具有層級關系,共同描述了一個 UI 組件的結構——

文章標題

章節標題

章節段落

一些其他信息

文章標題

章節標題

章節段落

一些其他信息

而組件修飾符 .ComponentName--modifierName 和組件狀態 .ComponentName.is-stateOfComponent 有時就不能很好地區分何時該用哪個了。就拿按鈕 CSS 組件來說,它的顏色、是否可用與尺寸,哪個該用修飾符?哪個算是狀態?

我給出一個比較簡單的判斷標準:如果是 UI 組件的特性,即不會因為什么條件而改變的,用修飾符;倘若會因某個條件滿足與否而變化,那就是狀態——

新增

批量刪除

應該注意的是,組件修飾符和組件狀態都是直接加在 UI 組件的根節點上的,也就是要跟在組件基類的后面,不能用于組件后代上。假如一個組件后代需要程序化地改變它本身的樣式,要用輔助工具類而不是狀態類。當一個組件后代的結構、功能等變得復雜時,要將其封裝成一個新的組件。

Sass 變量與 CSS 自定義屬性

在本系列文章所闡述的 UI 組件體系中,Sass 變量和 CSS 自定義屬性合稱為「風格組件」,它們負責主題風格的定制,是與設計體系(Design System)的結合點。其中,Sass 變量是在編輯時/編譯時,CSS 自定義屬性則是在運行時。

在這里,Sass 變量與 CSS 自定義屬性的命名方式比較類似,它們大概都是 -[-descendent-name|-modifier-name][-state]-(variable-name|property-name) 的形式。

由于我在基于本系列文章所闡述的思想做一套叫做「Petals」的半成品 UI 組件,因此之后的示例代碼中涉及到的 部分基本都會用 petals。

Sass 變量是以 $__petals 或 $petals 開頭,與組件名之間用 -- 連接,前者是內部使用(私有)的,上層開發者無需關心,后者是供外部在編輯時/編譯時定制用;CSS 自定義屬性則用 --petals 開頭,以 - 與組件名相連——/* 實際形式:--(variable-name|property-name) */

$__petals--button-font-size: --petals-button-font-size;

$__petals--button-line-height: --petals-button-line-height;

/* 實際形式:----(variable-name|property-name) */

$petals--button-primary-focus-color: var($__petals--primary-active-color, $petals--primary-active-color) !default;

$petals--button-primary-focus-bg: var($__petals--primary-active-bg, $petals--primary-active-bg) !default;

上文所說的 CSS 組件,即視覺組件,它是將樣式進行封裝,對外屏蔽細節;而風格組件相反,通過將視覺組件所用到的 CSS 屬性值動態化的方式達到樣式可定制化的目的,這就變得像 utility-first 的原子類一樣暴露了樣式細節。

但與 utility-first 的 CSS 框架不同的是,風格組件只給進行主題風格定制的人帶來了心智負擔,對其他的上層開發者并無影響。

業務無關

本系列文章主要討論的對象是業務無關的 UI 組件,在單說「UI 組件」或「組件」時也是指這個;而業務相關的 UI 組件,在本系列文章所闡述的 UI 組件體系中叫做「部件」。根據 UI 組件的通用性,可分為「通用組件」和「專用組件」。「通用組件」是能夠滿足大部分常規場景的 UI 組件,它們的集合通常會作為「組件庫」整體打包發布為一個軟件包;「專用組件」是為了解決某些特殊場景需求而存在的,像數據網格、各種編輯器等,這類一般都是單獨發包。

上面提到的「通用組件」和「專用組件」都是業務無關的 UI 組件。

UI 組件是什么?可以認為它是一個返回視圖結構的函數,而 UI 組件的屬性(prop)和事件(event)就是這個「函數」的參數。屬性是 UI 組件的外部與其內部進行主動通信的數據,事件則是進行被動通信的回調函數。

一個封裝得好的函數,它的參數應盡可能少,要想明白每個參數的語義,且必須確實有其存在的意義——UI 組件的屬性和事件的設計也該如此。

在設計 UI 組件的屬性時,先思考下要加的這個屬性是不是屬于這個 UI 組件本身的特性?若不是,那要加的屬性的值所對應的 UI 組件的特性是什么?如果這兩個問題都沒有得到答案,那么這個屬性可以不用加了。

UI 組件的屬性只應與其本身的特性有關,與業務意義無關——自身特性是自然特性,業務意義是附加特性。

比如,一個按鈕組件通常會有「主要」、「次要」和「危險」這幾種多少與業務沾邊的語義,那么組件的屬性該如何設計來滿足這種需求呢?

Ant Design 和 Element 的做法是將其作為 type 屬性的值或獨立成一個屬性——Ant Design 中的主要按鈕

Ant Design 中的次要(默認)按鈕

Ant Design 中的危險按鈕

Element 中的主要按鈕

Element 中的次要(默認)按鈕

Element 中的危險按鈕

按照上面說的 UI 組件屬性設計原則來看,「主要」、「次要」和「危險」作用到按鈕組件上的表現主要是顏色發生了變化,所以應該去用表示按鈕的自然特性「顏色」的 color 屬性來滿足同樣的需求——主要按鈕

次要(默認)按鈕

危險按鈕

紅色按鈕

黃色按鈕

藍色按鈕

若 UI 組件的某組特性是二元對立的,如「禁用」與「啟用」,則選擇默認不生效的那個作為屬性,且屬性值是布爾型,默認值為 false。

還是拿按鈕組件來舉例:如果默認是「禁用」,那就設計一個代表「啟用」的 enabled 屬性,其默認值是 false,只要組件在被使用時傳入了 enabled,就變成了「啟用」狀態;反之亦然。

另外,UI 組件的屬性值盡可能是簡單數據類型,也就是數字、字符串等。

業務相關

業務相關的 UI 組件,即上文所說的「部件」,因其關注點與業務無關的 UI 組件不同,所以在設計時所遵守的原則和考慮的事情也不盡相同,甚至會大相徑庭。一般來說,會用到上下文與依賴注入等技術。

由于業務相關的 UI 組件不是本系列文章主要討論的對象,在此就不展開說了。

總結

前幾天在朋友圈立了個 flag——

本文就是該 flag 的「引子」。

歡迎關注微信公眾號【Coding as Hobby】(微信中搜「coding-as-hobby」)以及時閱讀最新的技術文章~ ;-)

總結

以上是生活随笔為你收集整理的封装html ui 控件,聊聊前端 UI 组件:组件设计的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。