摘要:第四集從零開始實現組件本集定位之前一直在忙別的事情現在終于閑下來好好把這個庫的文章寫一下本篇目的是承接上文把組件的功能全部實現為添加按鈕的很重要現在一般的按鈕都帶個圖案因為這樣符合人腦的快捷思維方便理解與記憶圖標按鈕
第四集: 從零開始實現(button組件2)
本集定位:
之前一直在忙別的事情, 現在終于閑下來, 好好把這個庫的文章寫一下
本篇目的是承接上文, 把button組件的功能全部實現
1: 為button添加icon
按鈕的icon很重要, 現在一般的按鈕都帶個圖案,因為這樣符合人腦的快捷思維, 方便理解與記憶.
計算realyIconColor
icon有默認的顏色, 但是如果按鈕式禁用狀態, 那么icon也要相應的置灰
computed: { realyIconColor() { if (this.disabled) return "#bbbbbb"; else return this.iconColor; } }
2: icon的位置
很少遇到需要上下左右布局的icon, 如果需要的話.
方案一: 移動
方案二: 多寫幾個icon組件, 通過判斷決定顯示誰
3: hover效果
方案一:
hover的時候出現灰色蒙層效果
被點下時, 按鈕縮小動畫
&:not(.is-disabled) { &:active { box-shadow: none; opacity: 0.7; transform: translateX(2px) translateY(2px) scale(0.9); } &:hover { background-color:rgba(0,0,0,0.1) } }
效果圖
方案二:
hover出現金屬光澤, bulingbuling的,金屬光澤.
被點下時, 按鈕縮小動畫
綜上分析, 金屬光澤流過可能成為一個公用屬性, 那么我直接寫一個公共的樣式吧 "cc-bling"
我的思路:
嘗試使用漸變的背景顏色, 然后用 ackground-position-x 控制背景的右移
此方案實踐起來不舒服, 而且并沒有做到"解耦合"的設計原則, 所以不用了
偽元素, 用一個偽元素加上背景色, 然后把這個元素從左至右劃過, 同時用動畫把它做得傾斜30度
這樣雖然多了個元素, 但是跟父級解耦了, 值得說的一點是, 傾斜之后高度不夠盛滿了, 簡單粗暴的
方式就是把高度定位多一些的, 這樣旋轉也不會導致高度不夠的狀態了.
let"go
在button.scss;里面添加
@at-root { @include commonType(cc-button--); .is-bling { //此屬性名在hover的時候才進行bling操作 &:hover { @extend .cc-bling; } } };
animation.scss
定義一個從左至右的動畫
@keyframes bling{ 0% { left: 0; } 100% { left: 300%; } }
extend.scss
定義具體的樣式把
.cc-bling { &:after { content: ""; position: absolute; background-image: linear-gradient(to right, rgb(232, 229, 229), white); left: 0; top: -20px; // 避免傾斜的時候頭部漏出尖角 width: 15px; height: calc(100% + 30px); // 避免旋轉時候出現高度不夠的情況 transform: rotate(-30deg); animation-name: bling; animation-duration: 1s; // 總用時 animation-iteration-count: infinite; // 無限循環 animation-timing-function: linear; // 勻速 } }
效果圖, 是動態的, 從左至右劃過.
4: 防抖與節流
介紹: 這種節流與防抖都是用戶自己做的, 至少按鈕這種東西本套組件庫就是要組件來做.
使用場景:
有一次,我寫注冊登錄頁面, 如果用戶在注冊的時候, 快速的點擊了兩下, 雖然跳到登錄成功頁面, 但是會彈出彈框, "該手機已被注冊", 原來是由于第一個請求把手機注冊了, 所以接下來的點擊事件的請求后臺當然返回的是已注冊, 所以這里就需要這樣的處理, 每次點擊有效之后的點擊n秒內無效, 防止連點, (防止變速齒輪, 想起了流星蝴蝶劍);
我們公司19年搞了個搶購活動, 可能發生這樣的場景, 用戶守著搶購按鈕, 不斷地點擊, 我們web端需要在每次用戶點擊的時候詢問后臺"活動開始了么?", 沒開始就給用戶彈tosat(下一章就做這個組件了),開始了才進入活動也或是訂單頁, 但是, 用戶如果是個金手指, 瘋狂把玩搶購鍵, 那就會發出大量的請求了,
我來說一下:
第一: 為什么不使用后臺返回的活動開始時間與本地的事件進行比對??
原因是用戶的本地時間并不是一個值得信賴的量, 平時可以作為一個參考, 但是像搶購這種分秒必爭的事情, 就要讓用戶與服務器時間同步起來了.
第二: 為什么不在第一次請求之后把時間戳記錄下來, 本地用計時器模擬計時??
原因是某些瀏覽器環境下, 用戶切出程序之類的一些操作, 他會殺掉計時器, 導致計時不準, 而這種問題暫時無法解決, 也監控不到, 所以為了分秒必爭保險起見.
最后只能是每次都請求一下, 那就需要, 比如說 每600毫秒內, 只讓用戶的點擊有效一次.
我們就不能單純的寫click事件了,要抽離出來進行蹂躪??.
dom
接值
props: { ..., shake: Number, // 防抖的秒數 throttle: Number, // 節流, 請輸入秒數 clickId: [String, Number], // 相同id的組件走一套計時. }
事件
click() { // 根據用戶的輸入, 來決定怎么計時. // 值得一提的是, clickId 相同的話我們是統一計時的, // 比如說: 三個按鈕, 點了其中一個, 其他的幾個在規定時間內,都會不可點擊 let clickType, num; if (this.throttle) { clickType = 1; num = this.throttle; } else if (this.shake && this.shake > 0) { clickType = 2; num = this.shake; } else if (this.shake && this.shake < 0) { clickType = 3; num = this.shake * -1; } prevent( this.clickId, () => { this.$emit("click"); }, num, clickType ); },
在之前的工作中自己寫過一個防抖與節流的函數, 這次就直接拿來用了
let preventList = {} const prevent = function(id, obj, time, model = 1) { switch (model) { case 1: model1(id, obj, time) break; case 2: model2(id, obj, time) break; case 3: model3(id, obj, time) break; default: } } // 模式1 不管點多少下每隔time秒,觸發一次 function model1(id, obj, time) { if (preventList["can" + id]) return obj() preventList["can" + id] = true preventList["time" + id] = setTimeout(() => { preventList["can" + id] = false }, time) } // 模式2 每次動作都有time的延時再執行,也就是所有點擊完事的時候執行一個 function model2(id, obj, time) { clearTimeout(preventList["time" + id]) preventList["time" + id] = setTimeout(() => { obj() }, time) } // 默認的模式, 模式3, 第一下點擊觸發, 之后時間內不觸發 function model3(id, obj, time) { if (preventList["can" + id]) { clearTimeout(preventList["time" + id]) } else { obj() preventList["can" + id] = true } preventList["time" + id] = setTimeout(() => { preventList["can" + id] = false }, time) } export default prevent
具體的使用
//后續涉及到防抖與節流的事件也都是走的這套程序;
下一篇
toast的封裝, 通過封裝toast讓我鞏固了好多"芝士"
組件的另一種寫法
end
這段時間作者辭職, 專心學源碼, 練習算法, 重學js, 重學node,重做自己的打包工具, 反正挺忙的,接下來的時間與精力主要放到這套組件上 同時也會出一些算法啊, 心得之類的文章, 歡迎同學們一起交流, 一起變得更優秀.
github:鏈接描述
個人網站: 鏈接描述
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/105845.html
摘要:第二集從零開始實現組件本集定位這套組件我本來是先從做的但是我發現每個組件都要用到這個組件如果沒有他很多組件沒法擴展而且本身不依賴其他組件所以還是先把它作為本篇文章的重點吧組件讀過源碼的同學都知道他們選擇的是字體圖標的方式來做組件的而我的這 第二集: 從零開始實現(icon組件) 本集定位: 這套ui組件我本來是先從button做的, 但是我發現每個組件都要用到icon這個組件, 如...
摘要:第二集從零開始實現組件本集定位這套組件我本來是先從做的但是我發現每個組件都要用到這個組件如果沒有他很多組件沒法擴展而且本身不依賴其他組件所以還是先把它作為本篇文章的重點吧組件讀過源碼的同學都知道他們選擇的是字體圖標的方式來做組件的而我的這 第二集: 從零開始實現(icon組件) 本集定位: 這套ui組件我本來是先從button做的, 但是我發現每個組件都要用到icon這個組件, 如...
摘要:第三集從零開始實現組件本集定位為什么要叫那因為我感覺這個組件細節比較多應該會講很多內容所以先把基礎功能在這一集實現下集去做拓展組件這是一個基本上每個工程都會用到的組件傳統的千篇一律的樣式仿佛按鈕不做的一樣就沒法用似的我偏要加一些別人沒加過的 第三集: 從零開始實現(button組件1) 本集定位: 為什么要叫1那, 因為我感覺這個組件細節比較多, 應該會講很多內容, 所以先把基礎功...
閱讀 2464·2021-11-23 09:51
閱讀 523·2019-08-30 13:59
閱讀 1829·2019-08-29 11:20
閱讀 2534·2019-08-26 13:41
閱讀 3244·2019-08-26 12:16
閱讀 733·2019-08-26 10:59
閱讀 3327·2019-08-26 10:14
閱讀 603·2019-08-23 17:21