在Vue
的世界中已經充滿了各類各樣的UI庫了,尤爲出名的有ElementUI、Iview、MuseUI等,這幾個也是咱們平常業務開發中常用的UI庫。只使用UI庫的工程師被調侃爲api調用師
,這算是一種工程師之間的鄙視了,這種鄙視早晚要還回去的。javascript
最近在家比較閒,嘗試着以成熟UI庫的視角來感覺下其的開發過程,看了這些優秀的代碼,真的以爲本身的代碼有點屎味
了!很少說了,讓咱們開始打造本身的UI庫吧,首先看下按鈕是怎麼開發出來的。css
在正式開發按鈕以前,咱們先看下按鈕是如何使用的,以及有哪些主要屬性或者功能。這對接下來的api定義是頗有用處的,意義重大。vue
按鈕的主要屬性有這麼幾點:java
其實還有更多的屬性,這裏咱們不贅述了,知道了某些屬性的開發過程,其餘的也只是照葫蘆畫瓢的;再來看下真實場景中是如何使用的:git
<xch-button color="primary" :disabled="true" :noBorder="true" circle size="m">按鈕</xch-button>
複製代碼
清晰的目錄規劃,能爲後面的代碼帶來意想不到的可讀性。一個項目隨着時間的推移,人員的變更,每每會變得愈來愈大,愈來愈難維護。能在前期就規劃好一切固然是最好的,可是又有幾人能作到呢。看下咱們這個按鈕組件的目錄:github
本項目使用的是vue-cli 4.0
腳手架生成的,和之前版本生成的目錄大體相同。咱們編寫的代碼基本都在src
目錄下,其中components
裏放的是咱們的.vue
文件,style
中放的是樣式文件,本項目咱們採用的是less,和其餘幾個css預處理器都差很少。更具體的代碼邏輯,在下文會依次詳細解說。vue-cli
本文的最低要求是你已經具有了vue的基礎知識
。在開發一個組件以前,咱們最好的作法是規劃好這個組件的能力和相關的屬性以及api。特別是api,輕易不要亂改,任何不兼容的修改都是不成熟的標誌,對組件的使用者來講也是不負責任的表現,這也是爲何咱們老是選擇成熟優秀框架的緣由,沒有人但願隔三差五去修改不兼容的代碼。迴歸正題,咱們首先定義下咱們須要的props:api
props: {
circle: Boolean, // 圓角
noBorder: Boolean, // 邊框
disabled: Boolean, // 可點擊
color: String, // 顏色
textColor: String, // 文本顏色
size: {
type: String,
validator(value) {
return ["l", "m", "s", "xs"].indexOf(value) != -1;
}
} // 按鈕大小
}
複製代碼
先說一下思想:這些傳入的props,多數是爲了控制某個樣式的class是否須要應用,好比,circle
傳入的話,就表明着應用class: btn-circle
,size
傳入'l'的話,就表明着應用class: btn-l
。其餘的屬性也都大體同樣。框架
上文也講了,props的傳入,其實多數是爲了控制某個樣式是否應用。咱們使用vue的對象語法<div v-bind:class="{ active: isActive }"></div>
來定義一個計算屬性buttonCls
控制着樣式class這一塊。less
computed: {
buttonCls() {
return {
[`${prefix}`]: true,
[`${prefix}-circle`]: !!this.circle,
[`${prefix}-no-border`]: this.noBorder === true,
[`${prefix}-${this.color}`]: !!this.color,
[`${prefix}-text-${this.textColor}`]: !!this.textColor,
[`${prefix}-${this.size}`]: !!this.size
};
}
}
複製代碼
整齊劃一的代碼真好看,其中變量是prefix
是本身定義的前綴,這樣能很好的區分其餘UI庫,ElementUI是以el-
開頭,Iview是以i-
開頭。這麼一操做,馬上高大上起來了。不愧是皇家按鈕
, 哈哈。
template
部分相對簡單些,主要是將props和計算屬性應用到button
標籤上:
<template>
<button
type="button"
:class="buttonCls"
:disabled="!!this.disabled"
@click="click"
>
<slot></slot>
</button>
</template>
複製代碼
寫到這裏,邏輯部分基本寫完了,一共50行不到的代碼,雖然沒有ElementUI的el-button
的功能齊全,但也算是麻雀雖小五臟俱全吧,有興趣的同窗能夠仿照el-button
進一步擴展。下面咱們重點學習下怎麼規劃和書寫整潔的less代碼(這部分代碼真的驚豔到我了,我以前一直不重視css的代碼)
在動手寫代碼以前,咱們先梳理下有哪些要點:
var.less
,這個習慣必定要養成,在編寫大型的項目或者插件庫的時候,面對堆積成山的代碼量,會複用代碼的人是快樂的
,剩下的就是和稀泥的人,天天痛苦不堪。button.less
less
語法是很強大的,平時用的最多的就是嵌套語法和變量模式,其實less
還有不少的強大的功能,好比函數,混合等,都是很值得咱們去好好理解和學習的咱們先看下var.less文件,裏面咱們定義了不少變量,好比,顏色、padding等,不只是button
組件會用到,之後的其餘組件也會用到,先大概看下:
@prefix: xch-;
// 顏色
@primary-color : #45b984;
@blue-color : #3B91FF; //info
@green-color : #13CE66; //success
@yellow-color : #FFAE00; //warn
@red-color : #E11617; //error
@white-color : #fff;
//Dark, Gray 1-4 more
@dark-color: #333333;
@dark1-color: #555555;
@dark2-color: #666666;
@dark3-color: #777777;
@dark4-color: #999999;
@gray-color: #c1c1c1;
@gray1-color: #d3d3d3;
@gray2-color: #eeeeee;
@gray3-color: #f3f3f3;
@gray4-color: #f5f5f5;
// 按鈕padding
@button-size-normal-padding: 8px 15px;
@button-size-l-padding: 10px 20px;
@button-size-m-padding: 7px 16px;
@button-size-s-padding: 5px 10px;
@button-size-xs-padding: 2px 6px;
// radius
@border-radius : 4px;
//font-size
@font-size : 14px;
// Animation
@animation-time : .3s;
@transition-time : .2s;
@box-shadow-button: 0 1px 1px 0 @gray2-color;
//disabled
@disabled-cursor: not-allowed;
@disabled-color: @dark4-color;
@disabled-border-color: @gray1-color;
@disabled-background-color: @gray4-color;
複製代碼
button.less
的代碼,我使用了註釋的方法,儘可能詳細的解說其中的奧妙
@btn-prefix: ~"@{prefix}btn"; // 定義前綴,這是UI組件庫通用的作法
// 定義一個函數,方便控制顏色的切換
// 其中的darken和lighten方法是less自帶的,變淺或者變深,甚是好用
.btn-color(@color, @percent: 10%) {
background-color: @color;
border-color: darken(@color, @percent);
color: @white-color;
&:hover{
border-color: lighten(@color, @percent);
background-color: lighten(@color, @percent);
}
&:active {
border-color: darken(@color, @percent);
background-color: darken(@color, @percent);
}
}
.@{btn-prefix} {
border: none;
outline: none;
padding: @button-size-normal-padding;
display: inline-block;
border-radius: @border-radius;
font-size: @font-size;
...
// 顏色切換的精髓
&.@{btn-prefix} {
&-primary{
.btn-color(@primary-color)
}
&-red {
.btn-color(@red-color);
}
...
&-no-border{
box-shadow: none;
border-color: transparent !important;
}
&-circle {
border-radius: 20px;
}
}
// 不可點擊時的樣式
&[disabled] {
cursor: @disabled-cursor;
background-color: @disabled-background-color;
border-color: @disabled-border-color;
color: @disabled-color;
&:hover {
background-color: @disabled-background-color;
border-color: @disabled-border-color;
color: @disabled-color;
}
}
// 控制按鈕大小,實際上是控制padding
&.@{btn-prefix}-l {
padding: @button-size-l-padding;
}
&.@{btn-prefix}-m {
padding: @button-size-m-padding;
}
...
}
複製代碼
最後就是將本組件註冊到全局,這部分代碼在入口文件main.js中,比較簡單就不累述了;感興趣的同窗能夠思考下怎麼定義另外一個組件button-group
來完成按鈕的組合使用。
還有些細枝末葉的代碼和具體的按鈕效果,這裏也沒有提到,能夠去源碼查看更多詳細的代碼。或者直接下載到本地,跑起來,運行下: git clone https://github.com/xch1029/vue-study.git
。附上一句內心話,本身去實現一些UI庫級別的代碼真的能提高不少
。