結合Vue實現344分割手機號碼

這一個小需求,斷斷續續解決了很久,中間一直存在各類bug,如今基本上已經徹底解決,所以,打算從頭至尾記錄一下,方便之後查詢。javascript

需求

開始的時候,仍是把需求簡單的說下:css

移動端中,彈出系統的數字鍵盤,實現344分割手機號

需求明確以後,下面就是分析需求,而後才能肯定實現方式:html

  1. 明確說明是移動端,那麼也就是說,兼容問題不須要考慮太多
  2. 若是要彈出系統的數字鍵盤,那麼符合條件的只有一種,那就是type="phone"的input輸入框
  3. 在輸入的時候,實現344分割手機號,這個時候就要監視輸入框中內容的變化,這個能夠結合Vue的watch來實現
  4. 手機號344分割,那麼輸入框中輸入的最大長度應該就是13了

通過分析能夠看出,實際須要使用的知識點並非不少。分析完成以後,下面就要來具體實現這個需求了。vue

實現

搭建結構

首先,在寫真正的程序以前,要把結構搭建完成,後續寫代碼直接在結構中寫就能夠了。html5

  1. 首先來搭建html5的代碼結構,而後自定義input的樣式(方便後續查看)
  2. 定義input輸入框,並設置typemaxlength
  3. 經過v-model實現數據的雙向綁定
  4. 引入vue.js並搭建基本的代碼結構
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <style type="text/css">
    /* 自定義input輸入框的樣式 */
    #app input { width: 100%; height: 50px; border: 1px solid red; font-size: 30px; outline: none; }
  </style>
</head>
<body>
  <div id="app">
    <!-- 設置type和maxlength,並實現數據雙向綁定 -->
    <input v-model="phone" type="phone" placeholder="請輸入手機號" maxlength="13">
  </div>
</body>
</html>

<script type="text/javascript" src="./vue2.4.2.js"></script>
<script type="text/javascript">
  var vm = new Vue({
    el: '#app',
    data() {
      return {
        phone: ''
      }
    },
    watch: {
      phone(newValue, oldValue) {
        // 具體的代碼在這裏實現
      }
    }
  })
</script>

分析輸入和輸出

在具體實現以前,首先要明白,輸入和輸出的分別觸發什麼樣的操做。
下面,咱們把watch中的newValueoldValue的值輸出,看一下規律。java

phone(newValue, oldValue) {
        // 具體的代碼在這裏實現
        console.group('< === 是不是輸入 === >')
        console.log("%c%s", "color:red", `${newValue.length > oldValue.length}`)
        console.groupEnd('< === 是不是輸入 === >')
      }

當在輸入框中輸入內容的時候:正則表達式

輸入

當在輸入框中刪除內容的時候:app

輸出

從分析能夠看出,在輸入的時候,長度是增長的,刪除的時候,長度是減小的。工具

刪除的具體實現

在刪除的時候,會出現兩個轉折點,就是在刪除第10個元素或者第5個元素的時候,要自動刪除空格。優化

很明顯,這裏出現了兩個條件,下標爲4的時候和下標爲9的時候,要去除字符串的空格。

phone(newValue, oldValue) {
        // 具體的代碼在這裏實現
        if (newValue.length > oldValue.length) {
          // ...
        } else {
          if (newValue.length === 9 || newValue.length === 4) {
            this.phone = this.phone.trim()
          }
        }
      }

代碼寫出了以後,看着有些不舒服,有沒有優化方案呢?

再次通過分析會發現,既然在下標爲4或9的時候,咱們作的事是去除空格,那麼就能夠根據去空格的特性(有空格去除空格,無空格不進行處理),直接只作去除空格的操做,不進行判斷了。

phone(newValue, oldValue) {
        // 具體的代碼在這裏實現
        if (newValue.length > oldValue.length) {
          // ...
        } else {
          this.phone = this.phone.trim()
        }
      }

如今,刪除的功能實現了,而且代碼也進行了優化,下面開始實現輸入的操做。

輸入的具體實現

下面來分析一下輸入的問題:

在輸入的時候,當值的長度小於3的時候,確定是原樣返回的;當值的長度大於等於3且小於7的時候,要增長一個空格;當長度大於等於7的時候,要增長兩個空格。這個時候就要牽涉到條件判斷了。

另外,在判斷值的時候,確定是判斷總數字的個數,所以是去除空格的。

phone(newValue, oldValue) {
        // 具體的代碼在這裏實現
        if (newValue.length > oldValue.length) {
          if (newValue.replace(/\s/g, '').length < 3) {
            this.phone = newValue.replace(/\s/g, '')
          } else if (newValue.replace(/\s/g, '').length >= 3 && newValue.replace(/\s/g, '').length < 7) {
            this.phone = newValue.replace(/\s/g, '').replace(/(\d{3})/, '$1 ')
          } else if (newValue.replace(/\s/g, '').length >= 7) {
            this.phone = newValue.replace(/\s/g, '').replace(/(\d{3})(\d{4})/, '$1 $2 ')
          }
        } else {
          this.phone = this.phone.trim()
        }
      }

個人天哪,這個代碼怎麼看着那麼亂,應該能夠優化的。因爲正則表達式是一個強大的工具,所以,能夠結合正則來優化。

首先,咱們能夠把空格做爲分割點,那麼空格以前的內容屬於一組,因此共分三組。第一組的長度爲3個數字,第二組和第三組的長度都是0-4個數字,所以,經過正則能夠簡化代碼:

phone(newValue, oldValue) {
        // 具體的代碼在這裏實現
        if (newValue.length > oldValue.length) {
          this.phone = newValue.replace(/\s/g, '').replace(/(\d{3})(\d{0,4})(\d{0,4})/, '$1 $2 $3')
        } else {
          this.phone = this.phone.trim()
        }
      }

簡化代碼

上面的代碼已經基本算精簡了,但是,若是使用三目運算符,還能夠更加精簡:

phone(newValue, oldValue) {
        // 具體的代碼在這裏實現
        this.phone = newValue.length > oldValue.length ? newValue.replace(/\s/g, '').replace(/(\d{3})(\d{0,4})(\d{0,4})/, '$1 $2 $3') : this.phone.trim()
      }

至此,該需求已經完成了,最後實際的代碼只有一句。

總結

其實這個需求很簡單,須要總結的東西很少,所以,在這裏把具體的代碼實現貼出來,方便後續使用:

<div id="app">
  <!-- 設置type和maxlength,並實現數據雙向綁定 -->
  <input v-model="phone" type="phone" placeholder="請輸入手機號" maxlength="13">
</div>


<script type="text/javascript" src="./vue2.4.2.js"></script>
<script type="text/javascript">
  var vm = new Vue({
    el: '#app',
    data() {
      return {
        phone: '' // 雙向綁定的數據
      }
    },
    watch: {
      phone(newValue, oldValue) { // 監聽
        this.phone = newValue.length > oldValue.length ? newValue.replace(/\s/g, '').replace(/(\d{3})(\d{0,4})(\d{0,4})/, '$1 $2 $3') : this.phone.trim()
      }
    }
  })
</script>
相關文章
相關標籤/搜索