0%

Vue.js 電商練習技術整理 -- 使用 VeeValidate 輕鬆建立表單驗證

文章目的

我們應該都有經驗在網路上購買東西,填寫資料時若資料填寫不完整,會導致表單無法送出,無法完成訂單程序,往往使用者在填寫訂單時會需要填入一些必要的資料。
本文章將用來記錄用 Vue.js 開發時如何使用 VeeValidate 來驗證使用者資料正不正確,若不正確就阻止資料的送出。

VeeValidate 簡介

VeeValidate 是 Vue.js 表單驗證的外掛套件,使用它我們只需在需要驗證的表單上加入一些特定語法就可以建立驗證,附上官方文件

VeeValidate 安裝及引用

套件安裝

一樣打開我們的終端機輸入npm install vee-validate --save 安裝至我們的 Vue Cli 裡,那當然也有 cdn 的方式,相關內容可以觀看官方文件。
這邊有一點要注意,因為此套件官方還有持續在更新,寫這篇文章時筆者是使用2.2.14版本,後來因為更新到3.x版本時,使用方法會有點不同,本篇文章還是以2.x版本為主要介紹,3.x版本會在後續作補充。
若要改安裝2.x版本的話,可以輸入npm install vee-validate@2.2.15 --save 即可,在這之前若已經安裝此套件的話,要先輸入npm uninstall vee-validate --save 將套件移除。

中文化安裝及引用

因為 VeeValidate 有支援中文,所以我們接下來要將 VeeValidate 引用至我們的專案,並且將其中文化。

中文化

為了支援中文,我們需要先在終端機輸入npm install vue-i18n --save

引用與設定

安裝完成後,來到進入點(main.js) import 以下幾支檔案:

1
2
3
import VeeValidate from 'vee-validate'
import zhTW from 'vee-validate/dist/locale/zh_TW'
import VueI18n from 'vue-i18n'

接著我們在下面做以下設定:

1
2
3
4
5
6
7
8
9
10
11
12
Vue.use(VueI18n)

const i18n = new VueI18n({
locale: 'zhTW'
})
Vue.use(VeeValidate, {
events: 'input|blur', //這是為了讓使用者離開該欄位時觸發驗證
i18n,
dictionary: {
zhTW
}
})

另外要記得在下面 new Vue 中把 i18n 載入,如下:

1
2
3
4
5
6
7
new Vue({
i18n,
el: '#app',
router,
components: { App },
template: '<App/>'
})

進行到這裡我們就完成中文化與引用的步驟了,每個 Vue 元件中可以正常使用 VeeValidate。

表單驗證設定

基本寫法

我們來到需要驗證的 html input 標籤,先來看看程式碼:

1
2
3
4
5
6
<div class="form-group">
<label for="username">收件人姓名</label>
<input type="text" class="form-control" name="name" id="username" :class="{'is-invalid':errors.has('name')}"
v-model="form.user.name" placeholder="輸入姓名" v-validate="'required'">
<span class="text-danger" v-if="errors.has('name')">姓名必須輸入</span>
</div>

上面是一個利用 Bootstrap 4 表單做出來的版型,這裡有幾個重點:

  • input 標籤內要設定 name這個屬性,屬性值的部分則是根據該欄位性質做設定,例:姓名就是 name,地址就是 address。
    當然屬性值根據當下情況自己命名即可。
  • **必須在 input 標籤裡加上 v-validate="'required'"**,這是為了讓系統知道這一個欄位是必填的。
  • 接著我們可以寫入提示文字效果,像是上面的「姓名必須輸入」,我們透過 v-if 去控制它若驗證錯誤就顯示文字,至於 errors.has('name') 括號填入我們剛剛說的 name 屬性值,它就會幫我們判斷 true or false ,當是 true 時驗證失敗,false 時驗證成功
  • VeeValidate 可以與 Bootstrap 4 的驗證效果共用,因此我們一樣可以利用 v-if 的方式來動態新增 is-invalid 這個 className 讓提示更加明顯。

    email寫法

    這邊要額外提到 email 欄位的驗證法,email 會跟其他資料欄位有點不一樣,因此分出來講解。
    一樣的我們先來看看程式碼:
    1
    2
    3
    4
    5
    6
    <div class="form-group">
    <label for="useremail">Email</label>
    <input type="email" class="form-control" name="email" id="useremail" :class="{'is-invalid':errors.has('email')}"
    v-model="form.user.email" placeholder="請輸入 Email" v-validate="'required|email'">
    <span class="text-danger" v-if="errors.has('email')">{{errors.first('email')}}</span>
    </div>
    這邊有兩個地方跟基本寫法不太一樣。
  • 在我們設定 v-validate="'required|email'" 時,需要在 required 後面加入 email,這樣在驗證時才會以 email 的格式來驗證。
  • 另外在驗證提示文字用**兩個中括號包覆填入 errors.first(‘email’)**,會顯示 VeeValidate 的預設文字,它會根據 email 驗證的各種狀態來顯示不同的提示文字,我們一開始設定的中文化也在這邊派上用場,提示文字會是中文。

    驗證方法設定

    進行到這邊我們的表單已經能正常驗證,但是這僅僅是效果,若我們搭配 API 去設計表單的話依然一樣會將資料送出,因此我們需要利用方法來阻止 API 的接取,根據官方提供的寫法,可以這樣寫:
    1
    2
    3
    4
    5
    6
    7
    8
    this.$validator.validate().then((valid) => {
    if (valid) {
    // 當驗證成功時執行 AJAX 的行為
    })
    } else {
    // 驗證失敗產生的行為
    }
    })
    上述的方法可以加在 submit 後觸發的事件內。

補充–VeeValidate 3.x 使用方法介紹

有鑑於現在此套件版本已更新,使用方法與過往 2.x 有些許不同,因此透過補充的方式來記錄方法。

安裝與引用

我們在終端機輸入 npm install vee-validate --save,即可安裝最新版本的套件。
接著我們在 main.js 做引用,引用方法如下:

1
2
3
4
5
6
7
8
9
10
11
import Vue from 'vue';
import { ValidationProvider, extend } from 'vee-validate';

// Add a rule,此範例中添加了一個名為'secret'的規則,若 value 值不為 'example',就會回饋 message 裡的文字。
extend('secret', {
validate: value => value === 'example',
message: 'This is not the magic word'
});

// Register it globally
Vue.component('ValidationProvider', ValidationProvider);

你一定會發現多了一個 add rule,3.x 版本對於驗證規則添加了更多的彈性,我們可以自訂規則並在不同驗證中引用我們所需要的驗證規則。

使用方法與簡單功能介紹

現在我們知道 3.x 版本帶給我們更多的彈性,也帶給我們更多強大的功能,筆者會介紹幾個實用的基本功能,其他就要麻煩去看官方文件囉~

基本用法

1
2
3
4
<ValidationProvider rules="required|secret" v-slot="{ errors }">
<input v-model="email" type="text">
<span>{{ errors[0] }}</span>
</ValidationProvider>

我們透過引用 component 的方式來使用它,rules 對應的就是我們自定的規則囉,若添加 required 會讓系統了解到該欄位是必填,驗證起來也更加嚴謹喔!
errors[0] 則代表驗證錯誤的話就會顯示該規則底下定義的 messages。

驗證內容長度

1
2
3
4
<ValidationProvider rules="min:3" v-slot="{ errors }">
<input v-model="value" type="text">
<span>{{ errors[0] }}</span>
</ValidationProvider>
1
2
3
4
5
6
7
extend('min', {
validate (value, args) {
return value.length >= args.length
},
params: ['length'],
message: '長度不夠'
})

有時候我們會需要驗證使用者輸入的內容長度,這時候我們就可以利用 VeeValidate 來幫助我們驗證。
範例中可以看到 component 的 rules 部分我們採用了名為 ‘min’ 的規則,並規定長度至少要 3 以上。
js 中 args 這個參數就是我們傳進來的 3,我們可以這樣靈活的控制我們的內容長度。

彈性調整驗證提示文字

在前面的範例中,我們知道可以利用 rules 裡的 message 來提示使用者驗證結果,這邊要介紹一個彈性的提示文字寫法。

1
2
3
4
5
6
extend('positive', value => {
if (value >= 0) {
return true
}
return 'The {_field_} field must be a positive number'
})
1
2
3
4
5
6
7
8
<ValidationProvider
name="年紀"
rules="positive"
v-slot="{ errors }"
>
<input v-model="value" type="text">
<span>{{ errors[0] }}</span>
</ValidationProvider>

這邊可以看到 js 中 return 了 {_field_} 並搭配了一些文字,**{_field_}用意是它會替換成我們 component 裡的 name**,有沒有很方便,這樣我們只需引用同一個規則就能根據 name 呈現不同的提示文字了。

email 規則驗證

接下來我們來談談信箱驗證,VeeValidate提供了幾個規則供我們使用,這些規則會針對一些特定的內容作驗證,要注意的是這些規則需要我們自行安裝進來。
這次的 email 我們就要使用 VeeValidate 提供的規則做驗證,讓我們先來安裝規則吧!

1
2
3
4
5
6
7
8
import { required, email } from 'vee-validate/dist/rules'

extend('email', email)

extend('required', { // 這邊可以改寫我們 email 告知使用者是必填欄位的提示文字
...required,
message: 'This field is required'
})

一樣來到 main.js 我們將 email 規則 import 進來。

1
2
3
4
<ValidationProvider name="email" rules="required|email" v-slot="{ errors }">
<input type="email" v-model="value">
<span>{{ errors[0] }}</span>
</ValidationProvider>

接著在需要 email 驗證的地方將規則引用即可。
因為 VeeValidate 提供的規則會在驗證時顯示預設提示文字,身為台灣人就會有困擾,如果我提示文字想要是中文怎麼辦呢?
這時我們就可以用到 VeeValidate 提供的本地化方法囉!

本地化

我們來看看範例程式碼,了解如何本地化吧。

1
2
3
4
import { localize } from 'vee-validate'
import TW from 'vee-validate/dist/locale/zh_TW.json'

localize('zh_TW', TW)

只需短短的3行就完成提示文字本地化囉~ 當然 VeeValidate 提供了很多語言的本地化,甚至還有客製化提示文字,但這比較進階的用法筆者就不多提,提供連結供參考—本地化官方文件

根據驗證狀態改變視覺效果

接著我們來談談 validate 的視覺部分,我們可以根據 validate 的結果改變 css,來增加使用者的體驗,現在就讓我們來看看該如何加入吧!

1
2
3
4
5
6
7
8
import { configure } from 'vee-validate'

configure({
classes: {
valid: 'valid',
invalid: 'invalid'
}
})

我們先在 main.js 中將 configure import 進來,並可以在 configure 中根據不同驗證狀態,設定對應的 className,也就是說當該驗證狀態觸發時,我們就可以動態加入該 className,至於有甚麼狀態,可以查看官文文件了解—驗證狀態
接著我們就可以根據對應的 className 給他對應的 css,我們來看看以下範例吧!

1
2
3
4
5
6
7
8
<div>
<ValidationProvider name="email" rules="required|email" v-slot="{ errors, classes }">
<div :class="classes">
<input type="email" v-model="email">
<span>{{ errors[0] }}</span>
</div>
</ValidationProvider>
</div>

html 部分我們將 classes 透過 v-slot 載入,並透過 :class="classes" 動態綁定 className。

1
2
3
4
5
6
7
8
9
10
11
12
.invalid {
color: #EB0600;
}
.invalid input {
border: 1px #EB0600 solid
}
.valid {
color: green;
}
.valid input {
border: 1px solid green
}

還記得我們在 main.js 中 classes 針對了驗證成功與失敗設定了對應的 className(valid, invalid),因此我們就在 css 中根據這些 className 做設定,這樣就可以達到我們的效果囉。


參考資料

六角學院課程–Vue 出一個電商網站
官方方法使用
3.x官方文件