Element Form表單實踐(上)
阿新 • • 發佈:2020-05-20
![](https://img2020.cnblogs.com/blog/774496/202005/774496-20200520162145857-686298304.png)
>作者:小土豆biubiubiu
>
>部落格園:https://www.cnblogs.com/HouJiao/
>
>掘金:https://juejin.im/user/58c61b4361ff4b005d9e894d
>
>
>微信公眾號:土豆媽的碎碎念(掃碼關注,一起吸貓,一起聽故事,一起學習前端技術)
>
>碼字不易,點贊鼓勵喲~
# 前言
本篇文章主要是實踐一下`Element`中的 [`Form`](https://element.faas.ele.me/#/zh-CN/component/form) 表單元件。
> 本篇內容較為簡單,基本上是參照著文件將表單部分內容實踐了一下,後續會持續更新表單的一些常用功能。
>
> 同時下一篇文章 `Element Form表單實踐(下)` 將會分享專案開發中的一個表單實踐,記錄在這個過程中遇到的一些問題。
### 專案環境
為了簡單快速,我使用引入`cdn`靜態資源的方式搭建專案的開發環境。
```
Element Form表單實踐
{{message}}
```
環境準備好後,直接本地開啟頁面,就能看到效果。
![](https://user-gold-cdn.xitu.io/2020/5/7/171ed3df47eaccf2)
接著我們就開始`Element Form`表單的實踐。
# 使用Form元件
### 典型表單
首先按照官方文件我們先實踐一下`典型表單`。
`典型表單`的完整程式碼如下:
```html
Element Form表單實踐
{{message}}
-
立即建立
取消
```
瀏覽器開啟頁面:
![](https://user-gold-cdn.xitu.io/2020/5/7/171ed47358340c8e?w=736&h=604&f=png&s=15599)
可以看到表單元件已經顯示到了頁面上。
接下來,我們就這個表單元件的一些重要的特性進行學習。
# 表單屬性
> 表單屬性指的是設定在`el-form`元素上的屬性
### model
`model`屬性在前面的用法如下:
```html
```
`model`屬性是表單的資料,它繫結的`form`資料如下:
```javascript
form: {
name: '', // 活動名稱
region: '', // 活動區域
date1: '', // 活動時間-日期
date2: '', // 活動時間-時間
delivery: false, // 即時配送
type: [], // 活動性質
resource: '', // 特殊資源
desc: '' // 活動形式
}
```
`form`資料中的每一項分別對應表單中的一個`el-form-item`項,比如`name`對應的是活動名稱,那麼`el-form-item`寫法如下:
```html
```
> 這裡需要注意表單控制元件`el-input`的`v-model`並沒有繫結在`el-form-item`上:
> `input`控制元件對應的是`el-input`,`v-model`繫結在`el-input`上
> `select`控制元件對應的是`el-select`
> `checkbox`控制元件對應的是`el-checkbox-group`+`el-checkbox`,`v-model`繫結在`el-checkbox-group`上
> `radio`控制元件對應的是`el-radio-group`+`el-radio`,`v-model`繫結在`el-radio=group`上
> `switch`切換控制元件對應的是`el-switch`,`v-model`繫結在`el-switch`上
##### model繫結的form資料
接下來我們在探究一下這個`form`資料。
為了探究這個`form`資料,需要做下面的三件事:
01:在"立即建立"按鈕繫結的onSubmit函式中列印form資料
02:填寫表單資訊
03:點選"立即建立"按鈕,檢視form資料列印結果
第一步:在`立即建立`按鈕繫結的`onSubmit`函式中列印`form`資料。
```javascript
methods: {
onSubmit() {
console.log(this.form);
}
}
```
第二步:填寫表單資訊。
![](https://user-gold-cdn.xitu.io/2020/5/7/171eeb4cf42ebe0f?w=735&h=642&f=png&s=20588)
第三步:點選`立即建立`按鈕,檢視`form`資料列印結果。
![](https://user-gold-cdn.xitu.io/2020/5/7/171eeb58eb66c989?w=560&h=296&f=png&s=16333)
可以看到`form`資料包含了我們表單填寫的內容,我將`form`中的欄位、欄位的值和表單控制元件的關係梳理一下。
| 屬性/欄位 | 描述 | 控制元件型別 | 值 | 值的來源 | 型別 |
| :-------- |:---------| :-- | :-- | :-- | :-- |
| name | 活動名稱 | `input` |"element form表單實踐" | `input`輸入框的內容 | String |
| region | 活動區域 | `select` | "shanghai" | 選中的`select`的value值 | String |
| date1 | 活動時間-日期 | `el-time-picker` | Thu May 07 2020 00:00:00 GMT+0800 (中國標準時間) | 日期控制元件選擇的內容 | Date |
| date2 | 活動時間-時間 | `el-time-picker` | Thu May 07 2020 18:24:39 GMT+0800 (中國標準時間) | 時間控制元件選擇的內容 | Date |
| delivery | 即時配送 | `el-switch` | true | switch的選擇結果 | Boolean |
| type | 活動性質 | `checkbox` | ["美食/餐廳線上活動","地推活動"]| 選中的`checkbox`的label值 | Boolean |
| resource | 特殊資源 | `radio` | "線上品牌商贊助" | 選中的`radio`的label值 | String |
| desc | 活動形式 | `input` | "其他" | `input`輸入框內容 | String |
可以看到,表單`el-form`的`model`屬性繫結的`form`資料和表單中的內容是一致的,因此在日常專案開發中,表單資訊填寫完成,點選提交按鈕,可以直接將`this.form`作為請求的引數直接傳送給後端。
不過這裡很有必要對`this.form`這個資料進行一些完善。
在前面的程式碼中,最終`form`中的`type`值和`resource`值都是中文的結果,這樣的中文資料傳遞到後端,對後端的邏輯處理是很不友好的。
所以在日常的專案開發中,前後端會對這樣的資料有一個預設的約定關係:
```javascript
// 活動性質
{ 'foodOnlineActivities': '美食/餐廳線上活動',
'earthPushingActivity': '地推活動',
'offlineThemeActivities': '下線主題活動',
'brandExposure': '單純品牌曝光',
}
// 活動形式
{ 'online': '美食/餐廳線上活動',
'offline': '地推活動'
}
```
或者在簡單一些的約定:
```javascript
// 活動性質
{ 'foodOnlineActivities': '1',
'earthPushingActivity': '2',
'offlineThemeActivities': '3',
'brandExposure': '4',
}
// 活動形式
{ 'online': '1',
'offline': '2'
}
```
對應的我們的前端程式碼需要修改成下面這樣:
```html
美食/餐廳線上活動
地推活動
線下主題活動
單純品牌曝光
線上品牌商贊助
線下場地免費
```
接著在選擇對應的選項,檢視`form`資料的結果:
![](https://user-gold-cdn.xitu.io/2020/5/20/1723104f2169ec70?w=1280&h=666&f=jpeg&s=107928)
修改之後的`form`資料傳遞到後端以後,不管是對資料進行儲存或者判斷等邏輯,都比較簡單,而且不會因為中文的編碼而出現問題。
關於`form`資料最後的一點就是`form`的初始值。
我們看到`form`資料預設都是空值(`form`欄位的型別大多都不相同,這裡將上面的初始值統稱為空值),實際上我們可以為其指定`預設值`:即直接在`data`中給`form.xx`設定預設值。
> 這裡將上面`type`和`resource`設定的值恢復成了中文,專案開發中記得設定成上面的那種形式。
```javascript
form: {
name: '我是初始化設定的活動名稱', // 活動名稱
region: 'beijing', // 活動區域
date1: new Date(), // 活動時間-日期
date2: new Date(), // 活動時間-時間
delivery: true, // 即時配送
type: ['單純品牌曝光'], // 活動性質
resource: '線上品牌商贊助', // 特殊資源
desc: '我是初始化設定的活動形式' // 活動形式
}
```
設定了`預設值`後,我們重新整理頁面,表單中的內容就是我們設定的值。
![](https://user-gold-cdn.xitu.io/2020/5/8/171f3226fa27fa5d?w=672&h=614&f=png&s=18743)
> 注意:對於`select`、`checkbox`和`radio`這幾個控制元件,`form`欄位中的值必須要和對應控制元件的`label`值一致,否則控制元件匹配不到,對應的內容也就無法反填到表單中。
### rules
表單屬性`rules`是用於設定表單的驗證規則,我們來實踐一下。
```html
```
可以看到`:rule`作用在`el-form`上,並且綁定了一個變數`addFormRules`。
接著我們就在`addFormRules`中編寫活動名稱`name`的驗證規則。
```javascript
// 有部分未修改的程式碼省略
var vm = new Vue({
el: '#box',
data: {
addFormRules: {
name: [{
required: true, // name欄位是否必填,true:必填 false:非必填
trigger: 'blur', // 在什麼時候觸發驗證,blur:在元素失去焦點的時候驗證規則
message: "請輸入活動名稱", // 如果沒有填寫時的錯誤提示語
},{
min: 5, // 欄位最小長度
max: 10, // 欄位最大長度
trigger: 'blur', // 在什麼時候觸發驗證,blur:在元素失去焦點的時候驗證規則
message: "活動名稱長度在5-10個字元", // 不滿足規則時顯示的錯誤提示語
}]
}
}
})
```
在`addFormRules`裡面我們定義了`name`欄位,該欄位是一個數組,陣列的每一項又是一個`json`。
就我們編寫的這個驗證規則,陣列中的第一個`json`元素編寫的是活動名稱欄位的`必填驗證規則`,`json`中的每一個鍵值對的含義註釋中都有寫到;陣列中的第二個`json`元素編寫的是活動名稱欄位的`長度驗證規則`。
那麼到這裡還有最重要的一步,我們的這個規則才能生效:在`el-form-item`上設定`prop`屬性。
```html
```
可以看到`prop`屬性的值就是`form`中定義的`name`欄位,只有這樣`addFormRules`中定義的對`name`的校驗規則才能和對應的表單關聯起來,否則驗證規則是不會生效的。
> 這裡需要注意的是,表單`el-form`上繫結的`form`資料中的欄位、`prop`設定的值以及`rule`繫結的`addFormRules`資料中的欄位,這三個必須都要一致,否則校驗會出現問題。
### label-position、label-width、label-suffix
這三個表單屬性都是用於設定表單域的標籤。
![](https://user-gold-cdn.xitu.io/2020/5/14/17210d912f3a841d?w=713&h=200&f=png&s=7956)
`label-position`用於設定標籤域的對齊方式(預設右對齊);`label-width`用於設定標籤域的寬度;`label-suffix`用於設定標籤域的字尾。
```html
```
![](https://user-gold-cdn.xitu.io/2020/5/14/17210e8a23c2fd80?w=3840&h=3840&f=jpeg&s=1093072)
### status-icon
```html
```
![](https://user-gold-cdn.xitu.io/2020/5/14/17210f78db40a631?w=496&h=88&f=png&s=3759)
# 表單方法
### validate
表單方法`validate`是對整個表單進行校驗的方法,引數為一個`回撥函式`。
該`回撥函式`會在校驗結束後被呼叫,並傳入兩個引數:`是否校驗成功`和`未通過校驗的欄位`。若不傳入回撥函式,則會返回一個`promise`。
下面我們就來實踐一下這個表單方法。
> 主要的改動就是在提交表單的時候呼叫`validate`方法,打印出回撥函式中的兩個引數。
```html
立即建立
取消
```
表單驗證成功時`validate`和`failedInfo`的列印結果:
![](https://user-gold-cdn.xitu.io/2020/5/14/172111d5281efafc?w=497&h=317&f=png&s=16460)
表單驗證失敗時`validate`和`failedInfo`的列印結果:
![](https://user-gold-cdn.xitu.io/2020/5/14/172111f122a5d444?w=492&h=442&f=png&s=21876)
> 前面我們只編寫了`name`欄位的驗證規則,因此在表單提交呼叫`validate`方法時,只會對`name`欄位進行驗證。
其實對於我們日常的開發來說會比較關注第一個引數,當回撥函式中的第一個引數為`true`時,表示表單`驗證成功`,就可以將表單資料傳遞到後端;相反的當第一個引數為`falses`時,表示表單`驗證失敗`,我們就可以給使用者一個錯誤提示。
```javascript
methods: {
onSubmit() {
this.$refs['form'].validate((validate,failedInfo) => {
if(validate){
// 將表單資料傳送到後端
// 傳送 POST 請求
axios.post(url, this.form).then(function (response) {
// 處理後端返回的響應資料
});
}else{
// 提示使用者
this.$message({
message: '表單資料格式有誤,請檢查後重新提交.',
type: "error",
center: true
});
}
})
}
}
```
> 這裡有一定需要注意,回撥函式最好寫成箭頭函式的形式,這樣在回撥函式內部的`this`表示的是`Vue`例項物件。如果使用普通的函式宣告`function`,則回撥函式內部的`this`指向的是`windows`物件。
### resetFields
表單屬性`resetFields`對整個表單進行重置,`將所有欄位值重置為初始值`並且`移除校驗結果`。
> 本次改動就是將之前的`取消`按鈕改為`重置`按鈕,並且在點選`重置`按鈕的時候呼叫`resetFields`方法。
```html
立即建立
重置
```
![](https://user-gold-cdn.xitu.io/2020/5/18/17226d288f186810?w=495&h=647&f=gif&s=499988)
仔細檢視重置以後的結果,會發現只有活動名稱欄位的值恢復了初始值,而其餘我們修改了表單資訊的空間均沒有重置為初始值。
> 這裡需要注意`resetFileds`方法是將表單的值設定為`初始值`,而不是`空值`。`初始值`就是在元件的`data`中設定的值,所以我們點選重置的時候活動名稱這個空間的值變回了`我是初始化設定的活動名稱`。
這樣的效果顯然是不對的。
不過原因也很簡單,就是我們沒有給其他的表單項設定`prop`屬性。所以我們要注意,在使用`resetFileds`時,必須給表單項`el-form-item`設定`prop`值,否則無法進行重置。
```html
-
立即建立
重置
```
這裡需要特意說明的是為`活動時間`這個表單項設定`prop`屬性。
```html
-
```
那對比之前沒有設定`prop`的程式碼,還給`el-date-picker`外層多加了一個`el-form-item`元素。那也很好理解,因為活動時間這個包含了兩個`el-time-picker`,並且繫結的不同的`form`資料:`date1`和`date2`。而之前的寫法兩個`el-time-picker`都同在一個`el-form-item`元素中,那設定`prop`時只能設定一個值,所以`element`提供的解決方案就是分別給兩個`el-time-picker`在巢狀一層`el-form-item`元素,這樣就能分別設定`prop`屬性了。
現在我們在看一下重置按鈕的效果。
![](https://user-gold-cdn.xitu.io/2020/5/14/1721251e7e2dbc7e?w=495&h=647&f=gif&s=816782)
可以看到所有的表單項都重置成功。
# 表單項屬性
> 表單項屬性是指設定在`el-form-item`上的屬性
> 這裡在宣告一下一些叫法,以免產生疑惑
> 當描述`表單`時,對應的元素為`el-form`
> 當描述`表單項`對應的元素為`el-form-item`
### prop
這個屬性在前面實踐`表單驗證`、`表單重置`的時候用過。
那在日常開發中,`表單驗證`和`表單重置`是一個很常用的功能,因此很有必要在編寫程式碼的時候給表單項設定`prop`屬性,以免出現一些讓人疑惑的錯誤。
> 一定要注意`prop`屬性值的設定一定要和`form`表單繫結的欄位名稱一致
### label
label屬性設定的是表單標籤域的文字描述。
![](https://user-gold-cdn.xitu.io/2020/5/18/17227431f8bce32d?w=713&h=200&f=png&s=7956)
### size
表單元件的尺寸,共有三個可選值:medium / small / mini。
![](https://user-gold-cdn.xitu.io/2020/5/18/1722748c9b865136?w=727&h=75&f=png&s=5516)
### rules
這裡的`rules`是`表單項`的驗證規則,下面我們就`活動名稱`這個欄位進行驗證。
> 主要改動為將表單屬性`el-form`上的`rules`移除,在`活動名稱`對應的`el-form-item`上新增`rules`規則驗證。
```html
Element Form表單實踐
{{message}}
-
立即建立
重置
```
主要的程式碼如下:
```html
```
可以看到驗證規則新增到表單項`el-form-item`上和新增到表單`el-form`上的語法基本上是一致的。
接著看下驗證的結果。
![](https://user-gold-cdn.xitu.io/2020/5/18/172275da47d5fa40?w=495&h=647&f=gif&s=131461)
可以看到驗證規則已經生效了。
最後呢,還有一個操作想進行驗證一下,就是同時設定`el-form`和`el-form-item`上的`rules`。
```html
```
可以看到我將`el-form`上的`rules`又添加了回來。
`el-form`對活動名稱欄位的驗證規則是`不能為空`且`長度在5-10個字元`,而`el-item-form`上設定的規則只有`內容不能為空`。
我們再來看一下結果。
![](https://user-gold-cdn.xitu.io/2020/5/18/172276a28a0366c6?w=495&h=647&f=gif&s=185523)
可以發現只有`不為空`的驗證規則生效了,而長度驗證規則並沒有生效。所以結論就是`el-form`上的`rules`優先順序小於`el-item-form`上的`rules`規則驗證,當`el-form-item`上有定義欄位的驗證規則時,就會忽略對應的`el-form`上定義的欄位的驗證規則。
# 結束語
到這裡本篇文章就結束了,內容非常的簡單。
下一篇將會分享專案開發中的一個表單實踐,記錄在這個過程中遇到的一些問題。
# 關於
### 作者
小土豆biubiubiu
> 一個努力學習的前端小菜鳥,知識是無限的。堅信只要不停下學習的腳步,總能到達自己期望的地方
>
> 同時還是一個喜歡小貓咪的人,家裡有一隻美短小母貓,名叫土豆
### 部落格園
https://www.cnblogs.com/HouJiao/
### 掘金
https://juejin.im/user/58c61b4361ff4b005d9e894d
### 微信公眾號
土豆媽的碎碎念
> 微信公眾號的初衷是記錄自己和身邊的一些故事,同時會不定期更新一些技術文章
>
> 歡迎大家掃碼關注,一起吸貓,一起聽故事,一起學習前端技術
### 作者寄語
小小總結,歡迎大家指導~