16 處理表單數據與父子組件之間的數據交換

css

html

vue

目錄

處理表單輸入
1,單行文本
2,多行文本textarea
3,複選框checkbox
4,單選按鈕radio
5select下拉選擇框
6,全部input類型
父子組件的表單數據交換
1,使用sync
2,使用v-model模式
3,在子組件中使用model源碼

處理表單輸入

vue開發中獲取表單輸入的值,不是像JQuery那樣是主動查詢一個Html組件,而後訪問其屬性,取得它的值。
vue獲取表單輸入的數據,是經過被動的方式。在vue組件有輸入操做時,主動將數值綁定到data變量上;在提交表單前,從data數據源取得表單數據。
vue對有限個數的表單組件進行特別處理,包括:

1,單行文本

  
  
  
   
   
            
   
   
<!-- 單行文本 -->
<input type="text" v-model.trim="message" placeholder="edit me" />
<p>Message is:
{{ message }}</p>
其input type爲text。v-model.trim用於將用戶輸入值綁定在變量message上,trim這個修飾指令實現的是自動將輸入值去除首尾空格。
v-model實現的是一種雙向綁定。這是一種語法糖,上面的v-model至關於一個v-bind:value+一個v-on:input,以下所示:
  
  
  
   
   
            
   
   
<input v-bind:value="message" v-on:input="message=$event.target.value">
v-model表明的必定是屬性value與事件input的結合。vue開發裏全部支持v-model綁定的表單組件,都實現了對input事件的處理,即便原生的html組件沒有input事件也是如此。

2,多行文本textarea

  
  
  
   
   
            
   
   
<p>{{ message1 }}</p>
<textarea @input="handleInput" v-model.lazy="message1" placeholder="add multiple lines"></textarea>

3,複選框checkbox

  
  
  
   
   
            
   
   
<!-- 複選框 -->
<p>
<input @input="handleInput" type="checkbox" id="checkbox" v-model.number="checked" true-value="1" false-value="2" />
<label for="checkbox">
{{ checked }}</label>
</p>
其input type爲checkbox。v-model.number用於將複選框選擇的結果綁定到變量checked上,number修飾實現的是自動轉換輸入爲數值類型。
true-value與false-value定義的是真、假數值,即選擇與非選擇時的取值,默認是true與false。可是須要注意,這兩個屬性定義的選項值都是字符串,因此在v-model上須要使用number修飾。
複選框支持多個放在一塊兒,組合一組多選選項的集合:
  
  
  
   
   
            
   
   
<!-- 多個複選框 -->
<p>
<input type="checkbox" id="checkbox1" v-model="checked2" value="value1" />
<label for="checkbox1">value1</label>
<input type="checkbox" id="checkbox2" v-model="checked2" value="value2" />
<label for="checkbox2">value2</label>
<input type="checkbox" id="checkbox3" v-model="checked2" value="value3" />
<label for="checkbox3">value3</label>
<br/>
<span>Checked names:
{{ checked2 }}</span>
</p>
多個checkbox放在一塊兒,綁定到一個變量checked2上,就實現了多選效果。checked2的數據類型是一個數組。

4,單選按鈕radio

  
  
  
   
   
            
   
   
<!-- 單選按鈕 -->
<div>
<input type="radio" id="one" value="One" v-model="picked" />
<label for="one">One</label>
<br />
<input type="radio" id="two" value="Two" v-model="picked" />
<label for="two">Two</label>
<br />
<input type="radio" id="three" value="Three" v-model="picked" />
<label for="three">Three</label>
<br />
<span>Picked:
{{ picked }}</span>
</div>
其input type爲radio。

5,select下拉選擇框

  
  
  
   
   
            
   
   
<!-- 選擇框 -->
<div>
<select v-model="selected">
<option disabled value>請選擇</option>
<option :value="
{ number: 1 }">1</option>
<option :value="
{ number: 2 }">2</option>
<option :value="
{ number: 3 }">3</option>
</select>
<span>Selected:
{{ selected.number }}</span>
</div>
這是由select組件實現的,並非input組件了。選項option的value支持綁定一個js對象,在這樣設置時,select選擇的結果selected也是一個js對象。
下拉選擇框也同時多選:
  
  
  
   
   
            
   
   
<!-- 多選選擇框 -->
<div>
<select multiple v-model="selected2">
<option disabled value>請選擇</option>
<option :value="
{ number: 1 }">1</option>
<option :value="
{ number: 2 }">2</option>
<option :value="
{ number: 3 }">3</option>
</select>
<span>Selected:
{{ selected2 }}</span>
</div>
給select添加multiple屬性,下拉選擇框就會默認展開,同時支持按住SHIFT多選,選擇的結果selected2是一個數組。

6,全部input類型

上面僅是介紹了text、radio、checkbox三種input類型。事實上input組件功能十分豐富,它共有這些類型:
  
  
  
   
   
            
   
   
button 定義可點擊的按鈕(一般與 JavaScript 一塊兒使用來啓動腳本)。
checkbox 定義複選框。
colorNew 定義拾色器。
dateNew 定義 date 控件(包括年、月、日,不包括時間)。
datetimeNew 定義 date time 控件(包括年、月、日、時、分、秒、幾分之一秒,基於 UTC 時區)。
datetime-localNew 定義 date time 控件(包括年、月、日、時、分、秒、幾分之一秒,不帶時區)。
emailNew 定義用於 e-mail 地址的字段。
file 定義文件選擇字段和 "瀏覽..." 按鈕,供文件上傳。
hidden 定義隱藏輸入字段。
image 定義圖像做爲提交按鈕。
monthNew 定義 month year 控件(不帶時區)。
numberNew 定義用於輸入數字的字段。
password 定義密碼字段(字段中的字符會被遮蔽)。
radio 定義單選按鈕。
rangeNew 定義用於精確值不重要的輸入數字的控件(好比 slider 控件)。
reset 定義重置按鈕(重置全部的表單值爲默認值)。
searchNew 定義用於輸入搜索字符串的文本字段。
submit 定義提交按鈕。
telNew 定義用於輸入電話號碼的字段。
text 默認。定義一個單行的文本字段(默認寬度爲 20 個字符)。
timeNew 定義用於輸入時間的控件(不帶時區)。
urlNew 定義用於輸入 URL 的字段。
weekNew 定義 week year 控件(不帶時區)。
這些類型的input組件,均可以以一種自定義組件的方式使用之。

父子組件的表單數據交換

在vue開發中咱們常常會須要定義一個子組件,而後在這個子組件中獲取的表單數據,須要往父組件傳遞。這裏有三種傳遞方法:

1,使用sync

子組件代碼爲:
  
  
  
   
   
            
   
   
<template>
<input name="xxxx" v-model="currentValue" @input="handleModelInput" />
</template>
<script>
export default {
name: "ModelComponent2",
props: {
value: [String, Number, Date]
},
methods: {
handleModelInput() {
this.$emit("update:value", this.currentValue);
}
},
watch: {
// 屬性是隻讀的
value(newValue) {
this.currentValue = newValue;
}
},
data: () => ({
currentValue: ""
})
};
</script>
在子組件中,使用v-model獲取了原生input組件的輸入,並綁定在currentValue變量之上。監聽屬性value,是爲了將屬性value的值,極時同步到變量currentValue上,由於vue的屬性是單向的,並不能將一個屬性用於v-model。
v-model會自動更新輸入值到變量currentValue上,但不會自動派發事件。因此咱們須要將input事件綁定到函數handleModelInput上,當輸入變化時,在當前自定義組件內主動派發一個"update:value"事件,這個事件名稱採用的是"update:"+屬性名稱的格式,是一個vue語法約定。
父組件代碼爲:
  
  
  
   
   
            
   
   
<p>
<SyncComponent1 :value.sync="text1" ></SyncComponent1>
text1:
{{text1}}
</p>
運行效果:
使用這種sync模式,假設屬性爲xxx,要求爲:
  
  
  
   
   
            
   
   
1,在子組件中當屬性變化時,主動派發一個「update:xxx」事件,並附帶xxx的值
2,在父組件中,使用:xxx.sync將數據雙向綁定到一個data變量上
在這裏有一個問題,v-model與sync有什麼區別呢?貌似二者實現的功能是同樣的,sync實現的效果v-model也能實現。
不一樣點在於v-model用於表單數據綁定,指定了屬性名爲value,事件名爲input,不能變。而sync模式,在屬性名稱的設置上,在事件的派發時機上都比較靈活。

2,使用v-model模式

既然默認的vue表單組件能夠實現v-model雙向綁定,自定義組件一樣也能實現。
子組件代碼爲:
  
  
  
   
   
            
   
   
<template>
<input name="xxxx" v-model="currentValue" @input="handleModelInput" />
</template>
<script>
export default {
name: "SyncComponent2",
props: {
value: [String, Number]
},
methods: {
handleModelInput() {
this.$emit("input", this.currentValue);
}
},
watch: {
// 屬性是隻讀的
value(newValue) {
this.currentValue = newValue;
}
},
data: () => ({
currentValue: ""
})
};
</script>
父組件代碼爲:
  
  
  
   
   
            
   
   
<p>
<SyncComponent2 v-model="text2" ></SyncComponent2>
text2:
{{text2}}
</p>
運行效果與方法1是同樣的。能夠看到父組件代碼沒有變化。變化的是子組件代碼,再也不派發"update:value"事件了,取而代之的是派發input事件。這樣在父組件中,子組件就被裝扮成了和其它vue表單組件同樣了,也能夠直接使用v-model進行雙向綁定了。

3,在子組件中使用model

若是我不想或不方便派發input事件或update:xxx事件,怎麼辦?也有方法。可使用model。
子組件代碼:
  
  
  
   
   
            
   
   
<template>
<input name="xxxx" v-model="currentValue" @input="handleModelInput" />
</template>
<script>
export default {
name: "SyncComponent3",
model: {
prop: 'value',
event: 'change'
},
props: {
value: [String, Number]
},
methods: {
handleModelInput() {
// aync模式相比,發射的事件不一樣
this.$emit("change", this.currentValue);
}
},
watch: {
// 屬性是隻讀的
value(newValue) {
this.currentValue = newValue;
}
},
data: () => ({
currentValue: ""
})
};
</script>
model充許自定義一個屬性名稱和事件名稱,例如value和change,這樣當在子組件中派發change事件時,在父組件中能夠像方法2那樣使用子組件:
  
  
  
   
   
            
   
   
<SyncComponent3 v-model="text3" ></SyncComponent3>
text3:
{{text3}}
</p>

源碼

本文涉及的源碼能夠從這裏下載:
https://git.code.tencent.com/shiqiaomarong/vue-go-rapiddev-example/tags/v20200112

參考連接

  • http://www.fly63.com/article/detial/701git

  • https://www.jb51.net/article/142657.htm程序員

  • https://cn.vuejs.org/v2/guide/components-custom-events.html#自定義組件的-v-modelweb

  • https://cn.vuejs.org/v2/guide/forms.html#在組件上使用-v-modelapi

  • https://cn.vuejs.org/v2/guide/forms.html數組

  • https://www.runoob.com/tags/att-input-type.html緩存

相關閱讀

本文分享自微信公衆號 - 程序員LIYI(CoderLIYI)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。

相關文章
相關標籤/搜索