你可以用 v-model
指令在表单 <input>
、<textarea>
及 <select>
元素上创建双向数据绑定。它会根据控件类型自动选取正确的方法来更新元素
v-model
会忽略所有表单元素的 value
、checked
、selected
特性的初始值而总是将 Vue 实例的数据作为数据来源。你应该通过 JavaScript 在组件的 data
选项中声明初始值。
v-model
在内部为不同的输入元素使用不同的属性并抛出不同的事件:
- text 和 textarea 元素使用
value
属性和input
事件; - checkbox 和 radio 使用
checked
属性和change
事件; - select 字段将
value
作为 prop 并将change
作为事件。
<input v-model="message" placeholder="edit me">
<p>Message is: {{ message }}</p>
比如这个例子,使用v-mdel就能实现双向绑定。全局只维护一个message即可,屏蔽了底层的绑定逻辑,冰山上只露出了我们关心的message这个值
如果要实现同样的功能,我们需要这样写:
<input :value="message" @input="handleinput">
<p>Message is: {{ message }}</p>
methods:
# 响应用户动作
handleinput:(event){
const value = event.target.value;// 操作dom获得最新值
this.value = message;
}
# 修改message 对应的input value也改变
==》vue帮我们屏蔽了 操作dom的细节
v-model
会忽略所有表单元素的 value
、checked
、selected
特性的初始值而总是将 Vue 实例的数据作为数据来源。你应该通过 JavaScript 在组件的 data
选项中声明初始值。
<div>
<input type="checkbox" value="Jack" v-model="checkedNames">
<span>Checked names: {{ checkedNames }}</span>
</div>
这个例子是不是乍一看没啥问题,细细想咦,既然v-model是语法糖,那么岂不是这个input对应了两个value的绑定?
所以vue文档说了 v-model 会忽略表单元素的value值;
这么做的好处是什么?
<div id='example-3'>
<input type="checkbox" value="Jack" v-model="checkedNames">
<input type="checkbox" value="Job" v-model="checkedNames">
<input type="checkbox" value="Tom" v-model="checkedNames">
<span>Checked names: {{ checkedNames }}</span>
</div>
checkedNames:['Jack','Tom']===> 对应第1.3选项被选中
即多选下的数据收集很容易就被实现了
单选亦然
<div id="example-4">
<input type="radio" value="One" v-model="picked"> ==》 v-model绑定了是checked属性
<input type="radio" value="Two" v-model="picked">
<span>Picked: {{ picked }}</span>
</div>
picked:'one' 那么input就被选中了
相当于vue帮我们处理了 :checked="value===picked"即picked内含有value的值那么对应value就被选中
进阶版:
即再次验证了vue表单里的v-model的处理逻辑 是验证当前元素的 value 和 v-model的值如果匹配则当前元素则被选中;
<select v-model="selected">
<option v-for="option in options" v-bind:value="option.value">
{{ option.text }}
</option>
</select>
<span>Selected: {{ selected }}</span>
<script>
new Vue({
el: '...',
data: {
selected: 'A',
options: [
{ text: 'One', value: 'A' },
{ text: 'Two', value: 'B' },
{ text: 'Three', value: 'C' }
]
}
})
</script>
一个组件上的 v-model
默认会利用名为 value
的 prop 和名为 input
的事件,但是像单选框、复选框等类型的输入控件可能会将 value
特性用于不同的目的。
即
<input type="checkbox" id="subscribeNews" name="subscribe" value="newsletter">
# 此时value是 input的输入值
<input type="checkbox" id="coding" name="interest" value="coding">
# 此时的value是 单选框的解释值,对于checkbox来说真正的价值数据是 event.target.checked;
而vue并没有帮我们统一这个value即大块头地统一将通俗意义上的value作为vue的prop value;
vue将这个决定权交给了 开发者,即我们可以通过自定义表单组件的方式 规定改变 v-model的 默认语法糖;
vue默认的方案是:
v-model = prop(:value) + @input
开发者可以自定义,比如checkbox的 v-model = prop(:checked) + model
选项可以用来避免这样的冲突:
Vue.component('base-checkbox', {
model: {
prop: 'checked',
event: 'change'
},
props: {
checked: Boolean
},
template: `
<input
type="checkbox"
v-bind:checked="checked"
v-on:change="$emit('change', $event.target.checked)"
>
`
})
使用:
<base-checkbox v-model="lovingVue"></base-checkbox>
这里的 lovingVue 的值将会传入这个名为 checked 的 prop。
同时当 <base-checkbox> 触发一个 change 事件并附带一个新的值的时候,
这个 lovingVue 的属性将会被更新。
这个怎么感觉和这段话冲突了? 不是说vue内部已经帮我们处理好了吗?v-model
在内部为不同的输入元素 使用不同的属性并抛出不同的事件:
- text 和 textarea 元素使用
value
属性和input
事件; - checkbox 和 radio 使用
checked
属性和change
事件; - select 字段将
value
作为 prop 并将change
作为事件。
使用的意思是,主要这个属性改变了那么就会触发这个事件,这个事件触发了就会修改这个属性,即v-model的背后;
但不是说 v-model就是使用这个属性的值作为v-model的值而是 统一收集的 value这个属性的值;
===>
<p>check 多选</p>
<input type="checkbox" v-model="checkdata" value="check1">check1</input>
<input type="checkbox" v-model="checkdata" value="check2">check2</input>
checkdata:['check1']
watch:{
checkdata(){
用户操作更新 checkdata也会改变,但是收集到的数据是input下绑定的value
而不是 checked;如果我们自定义组件,修改model将v-model默认收集value改为check
那么此时checkdata !=['check1'] 而是 [true]
console.log(this.checkdata)
}
}