這裡給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 本篇文章記錄仿寫一個el-button組件細節,從而有助於大家更好理解餓了麽ui對應組件具體工作細節。本文是elementui源碼學習仿寫系列的又一篇文章,後續空閑了會不斷更新並仿寫其他組件。源碼在github上,大家可以拉下來,npm ...
這裡給大家分享我在網上總結出來的一些知識,希望對大家有所幫助
本篇文章記錄仿寫一個
el-button
組件細節,從而有助於大家更好理解餓了麽ui對應組件具體工作細節。本文是elementui源碼學習仿寫系列的又一篇文章,後續空閑了會不斷更新並仿寫其他組件。源碼在github上,大家可以拉下來,npm start運行跑起來,結合註釋有助於更好的理解
網站效果演示:ashuai.work:8888/#/myButton
GitHub倉庫地址:github.com/shuirongshu…
什麼是Button組件
按鈕用於點擊,一般是做事件的響應。
按鈕封裝效果圖
按鈕分類
- 單一按鈕
- 預設按鈕
- 主題按鈕(primary、success、warning、error)
- 按鈕大小(small、middle、big)
- 按鈕禁用(disabled)
- 按鈕載入(loading)
- 按鈕的圖標位置(預設圖標在按鈕文字左側)
- 圖標按鈕(沒有按鈕文字)
- 單一文字按鈕
- 按鈕組(按鈕組中有多個按鈕)
預設按鈕
預設按鈕很簡單,只是寫一個最普通的樣式即可
<button :class="[ 'myButton' ]" />
.myButton { display: inline-flex; align-items: center; justify-content: center; white-space: nowrap; box-sizing: border-box; padding: 12px 16px; background-color: rgba(0, 0, 0, 0.1); color: #222; border: none; cursor: pointer; user-select: none; // 不讓選中文字 transition: all 0.3s; font-size: 14px; } // 懸浮效果 .myButton:hover { background-color: rgba(0, 0, 0, 0.2); } // 按中效果 .myButton:active { background-color: rgba(0, 0, 0, 0.3); }
筆者這裡是將懸浮的效果和按中的效果,設置背景色越來越深。這樣的話,看著效果比較明顯
主題按鈕
所謂按鈕的主題,就是添加不同的類名,比如primary
主題的按鈕,就加上.primary
類名、success
主題的按鈕,就加上.success
類名。然後使用動態class
去添加即可(這裡使用動態class的數組用法)。如:
<button :class="[ 'myButton', type ]" />
變數type
的值源自於使用按鈕組件時,傳遞進來的type
參數
const typeArr = [ "", "primary", "success", "warning", "error", "text", "dangerText", ]; props:{ type: { // 按鈕主題類型 type: String, validator(val) { return typeArr.includes(val); // 這裡可以加一個校驗函數,其實不加也行 }, }, }
然後給不同type值加上對應的樣式即可。如下:
// primary樣式 .primary { background-color: #1867c0; color: #fff; } .primary:hover { background-color: #0854ac; } .primary:active { background-color: #033d7f; } // success樣式 .success { background-color: #19be6b; color: #fff; } .success:hover { background-color: #0ea459; } .success:active { background-color: #008140; } // warning樣式 .warning { background-color: #ffc163; color: #fff; } .warning:hover { background-color: #db952d; } .warning:active { background-color: #b97b1d; } // 等等type值樣式...
按鈕大小
按鈕大小可以使用padding
值的大小去控制,也可以直接使用zoom
縮放做控制
這裡使用動態style
搭配計算屬性的方式去控制,如下代碼:
// 不同的大小指定不同的縮放程度 const sizeObj = { small: 0.85, middle: 1, big: 1.2, }; props:{ size: String } <button :style="styleCal" /> computed: { styleCal() { return { zoom: sizeObj[this.size] // zoom縮放的值大小取決於傳遞進來的size值 } } }
按鈕禁用
按鈕禁用disable
沒啥好說的,主要是要註意loading
的時候,也要禁用掉,loading
載入的時候,不允許用戶再點擊。
<button :disabled="disabled || loading" />
props:{ loading:Boolean }
這裡註意一下,按鈕禁用的樣式也是通過動態class加上的,請往下看
按鈕載入
註意載入時樣式和載入按鈕圖標出來的時候,將其他的圖標給隱藏起來。(同一時刻,只能有一個按鈕圖標,這樣保證按鈕載入時簡潔一些)
<button :class="[ 'myButton', // 預設樣式 disabled ? 'disabledBtn' : '', // 動態加上禁用按鈕樣式 loading ? 'loadingBtn' : '', // 動態加上loading載入中按鈕樣式 type, // 主題樣式 ]" :disabled="disabled || loading" // 禁用時禁用,載入時也禁用 > <i class="el-icon-loading" v-if="loading"></i> <!-- 使用傳進來的圖標,通過動態style控製圖標和文字見的間隔,同一時刻下, 只能有一個圖標出現,所以有loading圖標了,就不能有別的圖標了 --> <i :class="icon" :style="styleGap" v-if="icon && !loading"></i> <slot></slot> </button>
按鈕的圖標位置
預設從左往右排列(圖標在左側、文字在右側),這裡我們可以使用彈性盒的方向flexDirection
屬性,來控制從左往右還是從右往左排列
<button :style="styleCal"/> styleCal() { // 控制縮放和指定預設圓角以及設置圖標在文字左側還是右側 let styleObj = { zoom: sizeObj[this.size], borderRadius: "5px", flexDirection: this.rightIcon ? "row-reverse" : "row", }; return styleObj; },
圖標按鈕和單一文字按鈕
這兩個也很簡單,
- 圖標按鈕註意加圓角的時機
- 單一文字按鈕的樣式要預留設置一份即可
然後動態控制一下即可
按鈕組
按鈕組註意事項:
- 首先將所有的按鈕的圓角全部去掉(這樣的話,所有的按鈕都是方方正正的按鈕了)
- 然後單獨給第一個按鈕
:first-of-type
的左上角和左下角的圓角設置一下 - 然後再給最後一個按鈕
last-of-type
的右上角和右下角的圓角設置一下 - 最後,按鈕組之間需要有間隔,這裡使用
border-right
做分割線 - 最最後,再把最後一個按鈕的右邊框去掉即可,如下css代碼
// 附上按鈕組樣式 .myButtonGroup > .myButton { border-radius: unset !important; // 給所有的按鈕都去掉圓角 border-right: 1px solid #fff; // 給按鈕加上分隔線條 } // 第一個按鈕左側圓角 .myButtonGroup > .myButton:first-of-type { border-top-left-radius: 5px !important; border-bottom-left-radius: 5px !important; } // 最後一個按鈕的右側圓角 .myButtonGroup > .myButton:last-of-type { border-top-right-radius: 5px !important; border-bottom-right-radius: 5px !important; border-right: none; // 同時,清除最後一個按鈕的右側邊框 }
代碼
複製粘貼即可使用,如果道友覺得代碼幫忙到了您,歡迎給咱github倉庫一個star哈