--- title: '11/02 VueJS 教學筆記: 正規表示法' disqus: hackmd --- 11/02 VueJS 教學筆記: 正規表示法 === 綱要 [TOC] 線上測試工具 --- https://regexr.com/ ![](https://i.imgur.com/seE9oSP.png) 常用規則 --- [Github範例](https://github.com/fortes1219/vue_0803/blob/0803/src/utils/validate.js) 新增一個`validate.js`並放置於 `src/utils` 下,需要驗證哪些資料就引入對應的項目 ```javascript= // URL export const reg_url = (val) => { const validate = /^((ht|f)tps?):\/\/[\w\-]+(\.[\w\-]+)+([\w\-.,@?^=%&:\/~+#]*[\w\-@?^=%&\/~+#])?$/ return validate.test(val) } // ID (TW) export const reg_twid = (val) => { const validate = /^[A-Za-z][12]\d{8}$/ return validate.test(val) } // TEL (北北基) export const reg_telTaipei = (val) => { const validate = /\d{2}-[2]\d{7}/ return validate.test(val) } // 手機號碼 (0987-987-987) export const reg_phoneType1 = (val) => { const validate = /\d{4}-\d{3}-\d{3}/ return validate.test(val) } // 手機號碼 (0987987987) export const reg_phoneType2 = (val) => { const validate = /\d{4}\d{3}\d{3}/ return validate.test(val) } // 帶國碼且有'+'的手機號碼 (886+987987987) export const reg_phoneType3 = (val) => { const validate = /\d{3}\+\d{3}\d{3}\d{3}/ return validate.test(val) } // 帳號是否合法 (字母開頭,允許下底線,6~16碼) export const reg_account = (val) => { const validate = /^[a-zA-Z][a-zA-Z0-9_]{5,16}$/ return validate.test(val) } // 中低強度的密碼,只能包含數字、字母、下底線,6~18碼 export const reg_pwdCommon = (val) => { const validate = /^[a-zA-Z][a-zA-Z0-9_]{5,16}$/ return validate.test(val) } // 高強度密碼,包含特殊字元,需含有大小寫和數字,8~18碼 export const reg_pwdStrong = (val) => { const validate = /^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{7,18}$/ return validate.test(val) } // Email // 以下詳解 ``` Email驗證的複雜性 --- 先對Email的正確格式有些共同標準的認知,比如: 1. 需要有`@` 2. 英文字開頭,不可由數字起始 3. 帳號通常可以接受`.`、`-`和`_` 4. `@`的前面能接受一個以上的英數與符號組合,如`-abc-`和`.abc.` 5. 符號間不可連接,也不可連續,比如不可能出現`user.-.acount@-mail.-com` 6. `@`後的Domain Name由`.`連接 7. `@`後的Domain Name結尾只能是英文字,不允許如`@any-mail.com123`這般不合理的格式 8. `@`的前後不可有符號 ```javascript= // Email export const reg_email = (val) => { const validate = /^\w+((-\w+)|(\.\w+))*\@[A-Za-z0-9]+((\.|-)[A-Za-z0-9]+)*\.[A-Za-z]+$/ return validate.test(val) } ``` ![](https://i.imgur.com/cSClj8i.png) 題解步驟:自定義驗證表單 ---- [Github範例](https://github.com/fortes1219/vue_0803/blob/0803/src/components/home/Regexp.vue) 確認`validate.js`已放置於 `src/utils` 下後,我們先來建立基本的表單外觀: ```htmlmixed= <template> <div class="page"> <h1>正則表單驗證範例</h1> <br> <!--不使用element UI 內建驗證的表單--> <el-form :model="form" label-width="100px" data-width="30rem"> <el-form-item label="姓名"> <el-input v-model="form.name.value" type="text" placeholder="請輸入姓名" /> <div class="el-form-item__error">{{ form.name.msg }}</div> </el-form-item> <el-form-item label="電話號碼"> <el-input v-model="form.tel.value" type="text" placeholder="ex: 02-23033824" @change="nativeValidate(form, 'tel')" /> <div class="el-form-item__error">{{ form.tel.msg }}</div> </el-form-item> <el-form-item label="手機號碼"> <el-input v-model="form.phone.value" type="text" placeholder="ex: 0987-987-987" @change="nativeValidate(form, 'phone')" /> <div class="el-form-item__error">{{ form.phone.msg }}</div> </el-form-item> <el-form-item label="Email"> <el-input v-model="form.email.value" type="text" placeholder="請輸入電子信箱地址" @change="nativeValidate(form, 'email')" /> <div class="el-form-item__error">{{ form.email.msg }}</div> </el-form-item> <el-form-item label="個人網站"> <el-input v-model="form.url.value" type="text" placeholder="ex: https://phchome.com" @change="nativeValidate(form, 'url')" /> <div class="el-form-item__error">{{ form.url.msg }}</div> </el-form-item> <div class="row horizontal end"> <el-button @click="nativeSubmit" :disabled="status">SUBMIT</el-button> </div> </el-form> </div> </template> ``` 處理`data`與`methods`的結構並且引入驗證規則: ```javascript= import { reg_telTaipei, reg_phoneType1, reg_email, reg_url } from "../../utils/validate" export default { data() { return { form: { name: { value: '', msg: '' }, tel: { value: '', msg: '' }, phone: { value: '', msg: '' }, email: { value: '', msg: '' }, url: { value: '', msg: '' }, }, submitDisabled: true // 送出按鈕的disabled狀態,true為禁用 } }, methods: { // native validate nativeValidate(target, key) { let checkTel = reg_telTaipei(target.tel.value) let checkPhone = reg_phoneType1(target.phone.value) let checkEmail = reg_email(target.email.value) let checkURL = reg_url(target.url.value) const arr = [checkTel, checkPhone, checkEmail, checkURL] // 驗證未通過則顯示msg內的訊息 switch (key) { case 'tel': checkTel == true ? target.tel.msg = '' : target.tel.msg = '電話號碼格式錯誤或未輸入' break case 'phone': checkPhone == true ? target.phone.msg = '' : target.phone.msg = '手機號碼格式錯誤或未輸入' break case 'email': checkEmail == true ? target.email.msg = '' : target.email.msg = 'Email格式錯誤或未輸入' break case 'url': checkURL == true ? target.url.msg = '' : target.url.msg = '網址格式錯誤或未輸入' break } // 用find只會撈回符合條件第一個值的特性,任何一個驗證規則沒通過就不能讓送出表單的按鈕被啟用 let result = arr.find((item) => { return item == false // 尋找array中的false }) // 當滿足所有條件後,result已經找不到false,會返回一個undefined,利用來判別此時要不要啟用Button result == undefined ? this.submitDisabled = false : this.submitDisabled = true console.log('form: ', arr, result) }, nativeSubmit() { if (!this.submitDisabled) { // 如果沒有啟用disabled,代表驗證條件皆符合 this.$message({ message: "登入成功", type: "success" }) // 接下來就是進入表單下一步動作,反之阻擋住 } else { this.$message({ message: "登入失敗", type: "warning" }) } }, } } ``` 使用 element UI 內建表單驗證 --- 以內建的方法來配置表單驗證會省下不少工夫,需要在HTML上設定一些特定的 Attribute: ```htmlmixed= <!--使用element UI 內建驗證 v-bind:rules--> <!--指定目前使用的v-model,並且給予參照名稱「loginForm」--> <el-form :model="form2" :rules="rules" ref="loginForm" label-width="100px" data-width="30rem"> <!--form item上指定prop == v-model.key--> <el-form-item label="姓名" prop="name"> <el-input v-model="form2.name" type="text" placeholder="請輸入姓名" /> </el-form-item> <el-form-item label="電話號碼" prop="tel"> <el-input v-model="form2.tel" type="text" placeholder="請輸入電話號碼" /> </el-form-item> <el-form-item label="手機號碼" prop="phone"> <el-input v-model="form2.phone" type="text" placeholder="請輸入手機號碼" /> </el-form-item> <el-form-item label="Email" prop="email"> <el-input v-model="form2.email" type="text" placeholder="請輸入電子信箱地址" /> </el-form-item> <el-form-item label="個人網站" prop="url"> <el-input v-model="form2.url" type="text" placeholder="個人網站網址"/> </el-form-item> <div class="row horizontal end"> <!--submit()中的參數帶el-form的ref名稱--> <el-button type="primary" @click="submit('loginForm')">SUBMIT</el-button> </div> </el-form> ``` 接著設置`data`與`methods`: ```javascript= export default { data() { return { // form {} // submitDisabled: true // ... form2: { name: '', tel: '', phone: '', email: '', url: '' }, rules: { tel: [{ required: true, pattern: /\d{2}-[2]\d{7}/, message: "電話號碼格式錯誤", trigger: "blur" }], phone: [{ required: true, pattern: /\d{4}-\d{3}-\d{3}/, message: "手機號碼格式錯誤", trigger: "blur" }], email: [{ required: true, pattern: /^\w+((-\w+)|(\.\w+))*\@[A-Za-z0-9]+((\.|-)[A-Za-z0-9]+)*\.[A-Za-z]+$/, message: "Email格式錯誤", trigger: "blur" }], url: [{ required: true, pattern: /^((ht|f)tps?):\/\/[\w\-]+(\.[\w\-]+)+([\w\-.,@?^=%&:\/~+#]*[\w\-@?^=%&\/~+#])?$/, message: "網址格式錯誤", trigger: "blur" }] } } }, methods: { // native validate // ... // element UI validate submit(formName) { this.$refs[formName].validate(valid => { console.log("valid: ", valid) if (valid) { this.$message({ message: "登入成功", type: "success" }) } else { this.$message({ message: "登入失敗", type: "warning" }) return false } }) } } } ``` ###### tags: `VueJS` `Regex`