---
# System prepended metadata

title: EXTRA-VueJS中如何限制User只能輸入特定字元
tags: [replace, regex, VueJS]

---

---
title: 'EXTRA-VueJS中如何限制User只能輸入特定字元'
disqus: hackmd
---

EXTRA-VueJS中如何限制User只能輸入特定字元
===

綱要

[TOC]

概論
---

我們雖然很常使用表單驗證來避免User輸入錯誤的資訊，但卻很難100%保證不會被特定方式跳過驗證、或者表單驗證沒有生效時，怎麼立即讓User認知到當前輸入的資料不正確。
這個範例會用一些正則表達式的方法來檢測當前被輸入的文字是否合乎欄位驗證標準，雖然在UX的角度來看稍微有點暴力。

replace()的進階用法
---

前一段時間我們上過了正則表達式的課程，理解如何判別 v-model 或字串中是否合乎特定規則。
但其實正則表達式在`replace()`上還能有更靈活的用法，這裡用一個替換網址內容的例子解釋：

[Codepen範例](https://codepen.io/fortes-huang/pen/bGNrGaj)

```javascript=
const regex = new RegExp("(https://google.com/result/)(\\d+)_(\\d+).aspx");
const url = "https://google.com/result/1017141_20361055.aspx";

const rep = url.replace(reg,"$1result.aspx?obj=$2&Id=$3");

console.log(rep)
console.log(reg.test(url))
```

![](https://i.imgur.com/TJHR9S0.png)

上面例子會發現，原本的網址：

`https://google.com/result/1017141_20361055.aspx`

被替換成了：

`https://google.com/result/result.aspx?obj=1017141&Id=20361055`

其實細節就藏在 ==$1, $2, $3== 這些編號裡面。

原本的正則規則：

`$1 = (https://google.com/result/)`
`$2 = (\\d+)`
`$3 = (\\d+)`

每一個 () 代表一個`Group`，依照正則中的先後順序可分別標上 $ + number
於是原本`url`中定義的網址，就在`replace()`後被替換了對應位置的字串。


讓 input 無法輸入不符合正則驗證的字元
---

[Codepen範例](https://codepen.io/fortes-huang/pen/JjoyoBp)

建構好`data`結構後，先新增一個`el-input`並且綁一個`v-on:input`事件：

```htmlmixed=
<template>
  <div>
    <div style="width: 500px; margin-bottom: 1rem;">
      <el-input v-model="testObj.floatNum" key="num1" type="text" placeholder="只能輸入最多三個整數位數，以及小數第二位的數字" @input="inputFilter($event, testObj)" />
    </div>
    <div style="width: 500px;">
      <el-input v-model="testObj.floatNum2" key="num1" type="text" placeholder="可整數位數不限制，但小數只能到第二位的數字" @input="inputFilter2($event, testObj)" />
    </div>
  </div>
</template>
```
```javascript=
<script>
export default {
  data() {
    return {
      floatNum: '',
      floatNum2: ''
    }
  },
  
  methods: {
    inputFilter(val, obj) {
      obj.floatNum = this.replaceInput(val, true)
    },
    inputFilter2(val, obj) {
      obj.floatNum2 = this.replaceInput(val, false)
    },
    
    replaceInput(value, limited = false) {
      value = value.replace(/^0*(0\.|[1-9])/, "$1") // 第一個字只能是數字
      value = value.replace(/[^\d.]/g, "") // 清除數字和「.」以外的字符
      value = value.replace(/^\./g, "") // 驗證第一個字元是否為數字
      value = value.replace(/\.{1,}/g, ".") // 只保留第一个「.」，不能有0.0.1之類的非法數值
      value = value.replace(".", "$#$").replace(/\./g, "").replace("$#$", ".")
      
      // 限制只能輸入至小數第二位
      value = value.replace(/^(\-)*(\d*)\.(\d\d).*$/, "$1$2.$3")
      
      // 正整數部分限制最多位數
      let limitedNum = 0
      if (limited) {
        limitedNum = 3
      } else {
        // 等於value的長度代表無限制
        limitedNum = value.length
      }
      value = value.indexOf(".") > 0 ? value.split(".")[0].substring(0, limitedNum) + "." + value.split(".")[1] : value.substring(0, limitedNum)

      return value
    }
  }
}
</script>
```
![](https://i.imgur.com/Szx8r7S.png)


###### tags: `VueJS` `replace` `regex`