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源创计划”,欢迎正在阅读的你也加入,一块儿分享。

相关文章
相关标签/搜索