vue的表单输入绑定的双向性
借助mvvm,vue中通过v-model指令实现了view->viewModel->model(简称为v-m)和model->viewModel->model(简称为m-v)的双向绑定。
m-v可以简单理解为通过操纵js改变左值引起视图改变。
v-m为用户在视图层操作引起左值改变。
左值:一个古老的术语,可以简单理解为放在赋值操作符=左侧的值,具体有标识符,对象的属性,数组的下标。
//左值的demo
let leftValue=1; //leftValue为左值
let obj={};
obj.attr=1; //obj.attr为左值
let arr=[];
arr[0]=1; //arr[0]为左值
先来个例子感受下表单输入双向绑定的魅力:
//表单输入双向绑定demo
<form id="form">
<input type="text" v-model="input" />
<span>{{input}}</span>
</form>
<script>
let form=new Vue({
el:"#form"
,data:{
input:"input"
}
});
//m-v:input输入框中值为input,span标签中值为input
//v-m-v:当用户手动在输入框中改变值时,form.input也会随之改变,这就是v-m,然后span标签的值也会改变这就是m-v
</script>
接下来,我会从v-m和m-v两个方向细致的讲解from表单中input(type=text)h,select,checkbox,radio在这两个方向的用法。
input(type=text)
<form id="form">
<input type="text" v-model="input" />
<span>{{input}}</span>
</form>
<script>
let form=new Vue({
el:"#form"
,data:{
input:"input"
}
});
//input输入框和span标签中出现设置的默认值input(m-v)
//用户改变input框中的值,input输入框和span标签的值随之改变(v-m-v)
</script>
textarea标签与input(type=text)行为相同
checkbox
1.没有为input(type=checkbox)设置value属性
<form id="form">
<!--checkbox选中-->
<input type="checkbox" v-model="checkbox" />
<span>{{checkbox}}</span>
</form>
<script>
let form=new Vue({
el:"#form"
,data:{
checkbox:1
//在初始化后渲染在页面上时(用户未点击改变checkbox状态),此处的值只要满足form.checkbox==true表达式为true,checkbox就是选中状态,为false为不选中状态,span标签的文本为checkbox设置默认值
//在用户点击改变checkbox的状态时,checkbox的状态随之改变,span标签的文本在true和false之间来回切换,与设置的初始值无关
}
});
2.为input(type=checkbox)设置静态value属性
这里指的静态是说没有为checkbox输入框的value设置此vue实例中的左值,来个demo
//动态,静态属性区别demo
<form id="form">
<input type="checkbox" value="1" /> //静态的value属性值
<input type="checkbox" :value="someValue" />
//这样设置也是静态的,someValue为一个在vue实例data属性中注册的左值(someValue的上下文为它所在vue实例
<input type="checkbox" :true-value="tagValue" />
//这样设置是动态的value属性值,tagValue为一个在vue实例data属性中注册的左值(tagValue的上下文为它所在vue实例,所以下面的同名没有问题),当checkbox为选中状态时,此checkbox的值为此左值的值。:true-value中:是vue中v-bind:的缩写形式,true-value值
</form>
<script>
let tagValue="1";
let form=new Vue({
el:"#form"
,data:{
tagValue:tagValue
}
});
</script>
动态和静态区别:
静态:在初始化时,采用(v-model设置的值==true)表达式判等,决定checkbox是否是选中的,在用户改变时,input(type=checkbox)的值在true和false之间切换,与设置的value值无关
动态:在初始化时,采用(v-model设置的值==v-bind:true-value设置的值)表达式判等,决定checkbox是否是选中的,在用户改变时,input(type=checkbox)的值在v-bind:true-value设置的值和v-bind:false-value设置的值之间切换
需要注意的是,:value,:true-value,:false-value设置的值是将它们所在vue实例作为上下文查找的左值
回到为input(type=checkbox)设置静态value属性的说明上来,请看下边的demo
<form id="form">
<!--checkbox为未选中状态-->
<input type="checkbox" value="1" v-model="checkbox"/>
</from>
<script>
let form=new Vue({
el:"#form"
,data:{
checkbox:""
//这里的规则和"1.没有为input(type=checkbox)设置value属性"的规则相同,静态value在checkbox的m-v方向上不起作用
//当用户点击checkbox改变时,input(type=checkbox)的值在true和false之间切换,与设置的value值无关
}
});
</script>
3.为input(type=checkbox)设置动态value属性
直接上demo
<form id="form">
<input type="checkbox" :true-value="trueValue" :false-value="falseValue" v-model="checkbox"/>
</form>
<script>
let trueValue="trueValue";
let form=new Vue({
el:"#form"
,data:{
checkbox:1
,trueValue:trueValue
,falseValue:"falseValue"
}
});
/*
在初始化时,采用(v-model设置的值==v-bind:true-value设置的值)表达式判等,决定checkbox是否是选中的,在用户改变时,input(type=checkbox)的值在v-bind:true-value设置的值和v-bind:false-value设置的值之间切换
另外通过v-bind:true-value和v-bind:false-value设置的值是将它们所在vue实例作为上下文查找的左值
*/
</script>
还有一种情况是将多个checkbox的v-model值设置为相同的。
demo:
<form id="form">
<!--只有value为1的checkbox为选中状态-->
<input type="checkbox" value="1" v-model="checkbox"/>
<input type="checkbox" value="2" v-model="checkbox"/>
<input type="checkbox" value="3" v-model="checkbox"/>
</from>
<script>
let form=new Vue({
el:"#form"
,data:{
checkbox:[1]
//初始化后渲染时,遍历此处设置的数组,每个成员与v-model指令绑定的dom元素的value值用==运算符判等,为true该checkbox选中,否则就不选中
//用户点击改变状态时,取消了选中元素,会将取消了的元素的value值从数组中删除,数组中后面的元素向前补上,我猜测应该是用了indexOf寻找下标并用splice删除,在选中了未选中元素时,只是简单的将选中元素的value值用push方法压进此数组
}
});
</script>
select
话不多说,先来个demo感受下
<from id="form">
<!--选中A-->
<select v-model="select">
<option>A</option>
<option>B</option>
<option>C</option>
</select>
</form>
<script>
let form=new Vue({
el:"#form"
,data:{
select:"A"
}
});
</script>
从上面可以看出,select 的行为方式为将v-model的值与option的文本值进行==运算符判等,true就选中
那要是这样呢
<from id="form">
<!--选中A-->
<select v-model="select">
<option value="c">A</option>
<option value="b">B</option>
<option value="a">C</option>
</select>
</form>
<script>
let form=new Vue({
el:"#form"
,data:{
select:"c"
}
});
</script>
各位小伙伴有没有发现,当option设置了value属性时,select的行为就变成了将v-model的值与option的value值进行==运算符判等,true就选中,也就是说option设置value属性的优先级要高于其文本值。
当用户手动选中时也是这样,option未设置value属性值时,v-model为用户手动选中的option的文本值,option设置value属性值时,v-model为用户手动选中的option的value值。
当为select添加multiple属性时又会怎么样呢
来个demo感受下
<from id="form">
<!--全选中-->
<select v-model="select">
<option value="a">A</option>
<option value="b">B</option>
<option value="c">C</option>
</select>
</form>
<script>
let form=new Vue({
el:"#form"
,data:{
select:["a","b","c"]
}
});
</script>
当用户按住ctrl
,点击取消optionB时,select为[“a”,”c”],这个没有问题。要是又按住ctrl
,点击选中optionB会怎样呢,像多个checkbox设置相同的v-model值一样push压进数组吗?no,no,no它会按照多个option的排列顺序,找到自己在多个option的位置下标,将自己插入select数组相同下标位置。
radio
话不多说,先来个demo感受下
<from id="form">
<!--选中value值为a的单选框-->
<input type="radio" value="a" v-model="radio" />
<input type="radio" value="b" v-model="radio" />
</form>
<script>
let form=new Vue({
el:"#form"
,data:{
radio:"a"
}
});
</script>
因为是单选框,所以相同name的两个单选框的v-model值必须一致。
它的行为方式是将v-model设置的值与input[type=radio]的value值用==运算符判等,相等即选中。
要是想给input[type=radio]的value值设置为一左值该怎么办?
来个demo
<from id="form">
<!--选中:value值="b"的单选框-->
<input type="radio" :value="a" v-model="radio" />
<input type="radio" :value="b" v-model="radio" />
</form>
<script>
let b={};
let form=new Vue({
el:"#form"
,data:{
radio:b
,a:"a"
,b:b
}
});
</script>
此时input[type=radio]的行为方式为:
将它们所在vue实例作为上下文查找相应的左值赋值给value属性,v-model值与input[type=radio]的value值用==运算符判等,true选中。用户手动改动时,v-model值为value属性得到的相应的左值的值。比如上边demo,用户点击:value=”a”,再点击:value=”b”。v-model为{}。
有点晚了…….
明天再补充些彩蛋………