我勸你別在數字鍵盤上刁難我——Vue自定義數字鍵盤元件

Chris威發表於2019-03-04

Vue自定義數字鍵盤

前言

最近做 Vue 開發,因為有不少頁面涉及到金額輸入,產品老是覺得用原生的 input 進行金額輸入的話 體驗很不好,天天催著我找時間優化,原生控制元件還有優化個毛線,回去等死吧~

絕望

既然要使用者體驗,而我又對原生控制元件感到很絕望,於是!我有一個大膽的想法….

我們自己動手寫一個!

廢話不多說,先上效果圖吧~

效果圖

效果圖

具體實現

佈局排版

<div class=`key-container`>
    <div class=`key-title`>請輸入金額</div>
    <div class=`input-box`>{{ money }}</div>
    <div class=`keyboard` @click.stop=`_handleKeyPress`>
        <div class=`key-row`>
            <div class=`key-cell` data-num=`7`>7</div>
            <div class=`key-cell` data-num=`8`>8</div>
            <div class=`key-cell` data-num=`9`>9</div>
            <div class=`key-cell` data-num=`D`>C</div>
        </div>
        <div class=`key-row`>
            <div class=`key-cell` data-num=`4`>4</div>
            <div class=`key-cell` data-num=`5`>5</div>
            <div class=`key-cell` data-num=`6`>6</div>
            <div class=`key-cell` data-num=`C`>清空</div>
        </div>
        <div class=`key-row`>
            <div class=`key-cell` data-num=`1`>1</div>
            <div class=`key-cell` data-num=`2`>2</div>
            <div class=`key-cell` data-num=`3`>3</div>
            <div class=`key-cell` data-num=`-1`></div>
        </div>
        <div class=`key-row`>
            <div class=`key-cell disabled` data-num=`-1`></div>
            <div class=`key-cell` data-num=`.`>.</div>
            <div class=`key-cell` data-num=`0`>0</div>
            <div class=`key-cell` data-num=`-1`></div>
        </div>
        <div class=`key-confirm` data-num=`S`>確認</div>
    </div>
</div>
複製程式碼
  • 佈局方面我全部採用了 div 元素來模擬,方便好用 (๑ŐдŐ)b
  • 鍵盤按鍵方面,每個按鈕都設定了其自定義屬性值 num ,目的就是為了區分按鍵後產生不同的效果
  • 事件繫結在了父級,通過捕獲來確定具體點選的元素

樣式程式碼我在這裡就不貼了,具體的我託管到 github 上了~

輸入判斷

對於鍵盤來說,最主要的就是輸入判斷,整個鍵盤的輸入都是先經過 _handleKeyPress 進行處理的

//處理按鍵
_handleKeyPress(e) {
	let num = e.target.dataset.num;

	//不同按鍵處理邏輯
	// -1 代表無效按鍵,直接返回
	if (num == -1) return false;

	switch (String(num)) {
		//小數點
		case `.`:
			this._handleDecimalPoint();
			break;
		//刪除鍵
		case `D`:
			this._handleDeleteKey();
			break;
		//清空鍵
		case `C`:
			this._handleClearKey();
			break;
		//確認鍵
		case `S`:
			this._handleConfirmKey();
			break;
		default:
			this._handleNumberKey(num);
			break;
	}
}
複製程式碼

可以看出,我將按鍵種類分為了,五大類,分別是 小數點刪除(退格)鍵清空鍵確認鍵數字鍵,分別對應不同的處理函式,接下來我們一一來分析~

  • 小數點,由於最多隻能輸入一個小數點,因此需要對其判斷,如果有小數點直接返回;沒有的話,也要分小數點是不是第一個輸入的字元,如果是就將其變成 0.,如果不是將小數點追加到當前字元末尾;

      //處理小數點函式
      _handleDecimalPoint() {
      	//如果包含小數點,直接返回
      	if (this.money.indexOf(`.`) > -1) return false;
      	//如果小數點是第一位,補0
      	if (!this.money.length)
      		this.money = `0.`;
    
      	//如果不是,新增一個小數點
      	else
      		this.money = this.money + `.`;
    
      }
    複製程式碼
  • 刪除(退格)鍵,處理起來比較方便,先判斷當前輸入的字元是否為空,如果沒有字元,直接返回,否則將字串最後一個字元刪除;

      //處理刪除鍵
      _handleDeleteKey() {
      	let S = this.money;
      	//如果沒有輸入,直接返回
      	if (!S.length) return false;
      	//否則刪除最後一個
      	this.money = S.substring(0, S.length - 1);
    
      }
    複製程式碼
  • 清空鍵,邏輯最簡單,直接將當前字元清空即可;

      //處理清空鍵
      _handleClearKey() {
      	this.money = ``;
      }
    複製程式碼
  • 確認鍵,判斷當前字元是否為空,為空就提示資訊並返回,不為空我們也要進行判斷,如果輸入的是 8. 這種格式,我們需要對齊格式化成 8.00 這種形式,否則就直接保留兩位小數,最後在觸發 回撥,並把結果作為引數傳遞過去;

      _handleConfirmKey() {
      	let S = this.money;
      	//未輸入
      	if (!S.length){
      		alert( `您目前未輸入!` )
      		return false;
      	}
    
      	//將 8. 這種轉換成 8.00
      	if (S.indexOf(`.`) > -1 && S.indexOf(`.`) == (S.length - 1))
      		S = Number(S.substring(0, S.length - 1)).toFixed(2);
      	//保留兩位
      	S = Number(S).toFixed(2);
      	this.$emit(`confirmEvent`,S)
      }
    複製程式碼
  • 數字鍵,邏輯也不是很複雜,主要先看其有沒有小數點,如果有小數點,那麼最多輸入兩位數字,如果沒有小數點,得判斷第一位輸入的是不是0 , 如果是0,那麼接下來就只能輸入小數點了,而且也要杜絕 0000 這種無效的輸入,因此我多加了一個判斷,否則就直接追加在當前字元後面即可;

      //處理數字
      _handleNumberKey(num) {
      	let S = this.money;
    
      	//如果有小數點且小數點位數不小於2
      	if ( S.indexOf(`.`) > -1 && S.substring(S.indexOf(`.`) + 1).length < 2)
      		this.money = S + num;
    
    
      	//沒有小數點
      	if (!(S.indexOf(`.`) > -1)) {
      		//如果第一位是0,只能輸入小數點
      		if (num == 0 && S.length == 0)
      			this.money = `0.`;
    
      		else {
      			if (S.length && Number(S.charAt(0)) === 0) return;
      			this.money = S + num;
      		}
    
      	}
    
      }
    複製程式碼

元件引入

元件準備好了,只需填好路徑,在對應的 components 中註冊後,直接放在頁面上使用使用即可,類似下面

<calculation @confirmEvent="_confirmEvent"></calculation>
複製程式碼

其中, _confirmEvent 是點選確認鍵的回撥,引數就是輸入的金額,我這裡只是簡單的列印而已~

_confirmEvent(res){
	console.log(res)
}
複製程式碼

效果就跟下面差不多,

確認效果圖

結語

怎麼樣,是不是很簡單,so easy , 再也不怕產品讓我天天使用者體驗了。
當然,我這裡只是寫了一個基礎,具體的還得切合自己的業務邏輯,感興趣的同學可以自己對其在進行封裝,實現純數字或者帶小數點直接的切換式鍵盤等,看你們發揮~

xx

完整程式碼,請戳這裡~

相關文章