您好,登錄后才能下訂單哦!
這篇文章將為大家詳細講解有關基于uni-app開發刻度尺組件的示例分析,小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。
小編最近接到一個任務,就是在輸入數值的時候不再使用傳統的鍵盤了,而是用拖拉尺子的形式選擇數值,大概長這樣:
其實這需求不是第一次提出來了,在我們的應用第一版的時候產品就想這樣做。
當然小編我當時剛接到這個任務的時候是拒絕的,你不能讓我做,我就馬上去做,第一我要調研一下,因為我不想花那么多時間成本開發出這個組件再加一些特技上去,
滑動超過邊緣還能duang一下彈回來,但是其實用起來還沒直接鍵盤輸入數字來得方便,這樣領導出來一定會罵我;后面經過一番調研和時間評估,最終選擇了另一套方案:
自己寫了一套數字鍵盤,比刻度尺簡單很多,也不怎么耗性能,用起來還挺方便。
為什么不用系統自帶鍵盤呢?這個不用說,大家都知道手機瀏覽器調用系統自帶鍵盤有多惡心。
然而,該應用迎來了第二個版本,產品又把刻度尺拿了出來并揚言:“要砍需求先砍我!”。
不過確實,第二版有了更加復雜的場景,選擇的數值需要限制范圍,而且范圍大小會隨著一些條件不斷變化,要想用戶能直觀并快速地輸入正確的數值,只能是刻度尺了。
然后經過小編兩分鐘的深思熟慮,最終把任務接了下來。
首先我們來看看刻度尺有哪些特點。
可以滑動;
根據滑動距離輸出數值;
滑過頭了會自動回彈;
看起來,我們可以基于uni-app提供的scroll-view組件來開發,該組件有提供以下屬性正好適合我們的刻度尺特性:
屬性名 | 類型 | 默認值 | 說明 |
---|---|---|---|
scroll-x | Boolean | false | 允許橫向滾動 |
scroll-left | Number/String | 設置橫向滾動條位置 | |
scroll-with-animation | Boolean | false | 在設置滾動條位置時使用動畫過渡 |
@scroll | EventHandle | 滾動時觸發,event.detail = {scrollLeft, scrollTop, scrollHeight, scrollWidth, deltaX, deltaY} |
然后第二步,需要計算刻度。
小編先設置好了默認每個刻度占10像素;
const GUTTER = 10;
然后就開始計算我們一共需要多少個刻度,其實很簡單,就是你需要多少刻度,就傳進來一個最大最小值,然后用最大值減去最小值,就是刻度的數量了;
這時候會出現一個交互問題,因為刻度尺的選擇標是放在屏幕中間的,所以刻度尺的邊界是需要顯示多余的刻度用來充滿屏幕,于是小編就決定生成相當于兩倍于屏幕寬度的多余刻度;
// 多余的刻度數量 const extraGridCount = Math.ceil(window.innerWidth / GUTTER); // 生成刻度數組 this.gridList = Array.from(Array(this.gridMax - this.gridMin + extraGridCount * 2)).map((_, i) => { const num = i + this.gridMin - extraGridCount; const displayNum = this.decimal === 1 ? num / 10 : num; return { num, displayNum, isLongGrid: num % GUTTER === 0, showText: num % GUTTER === 0 && num >= this.gridMin && num <= this.gridMax } });
刻度數組內每個元素就是一個刻度對象,包含了以下屬性:
刻度數值
刻度顯示的數值(顯示的數值可能會與實際數值不一致,是為了擴展小數用的)
是否是長刻度(因為刻度尺每隔10個就會出現一條長刻度)
是否顯示刻度的數值(只有長刻度和有效刻度才會顯示數值)
數組生成好,就可以根據數組來渲染整個刻度尺了;
<u-row v-if="show" class="grid-wrapper" align="top"> <view class="grid-item" :class="{'long': item.isLongGrid}" v-for="(item, i) in gridList" :key="i" : > <text class="grid-num" v-if="item.showText" >{{item.displayNum}}</text> </view> </u-row>
渲染完畢之后,就可以通過一些算法計算刻度尺的初始位置了。然后通過scroll事件,在刻度尺滑動過程中計算數值;
scroll(e){ const scrollLeft = e.detail.scrollLeft; let value = Math.floor((scrollLeft - this.offsetScroll + this.gridMin * GUTTER) / GUTTER); if(value < this.gridMin){ value = this.gridMin; }else if(value > this.gridMax){ value = this.gridMax; }}
其中offsetScroll 就是多余的那部分刻度,需要減掉的,還要判斷一下是否小于最小值或者是否大于最大值; 接下來就是刻度尺的回彈了,當滑動超過最大值或最小值時,需要往回彈,在視覺上與計算好的數值保持一致; 其實也只是在滑動結束時算一下刻度尺是否應該回到邊界就好了,動畫上scroll-view已經幫我們解決好了;
adjustScrollPosition(){ /** 滾動結束后調節滾動位置 */ if(this.actualScrollLeft < this.offsetScroll){ this.scrollLeft = this.offsetScroll + (Math.random() / 100); } else if(this.actualScrollLeft > (this.gridMax - this.gridMin) * GUTTER + this.offsetScroll){ this.scrollLeft = (this.gridMax - this.gridMin) * GUTTER + this.offsetScroll + (Math.random() / 100); } else if(Math.floor(this.actualScrollLeft - this.offsetScroll) % GUTTER !== 0){ const dryScrollLeft = this.actualScrollLeft - this.offsetScroll; this.scrollLeft = dryScrollLeft - dryScrollLeft % GUTTER + this.offsetScroll; } }
關于“基于uni-app開發刻度尺組件的示例分析”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,使各位可以學到更多知識,如果覺得文章不錯,請把它分享出去讓更多的人看到。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。