v-model
是 Vue.js 中用于实现双向数据绑定的指令,它结合了数据绑定和事件监听,使得表单元素(如 input
、textarea
、select
等)的值能够与 Vue 实例中的数据保持同步。
1.原理概述
v-model
的本质是语法糖,它是 :value
和 @input
指令的结合。对于不同的表单元素,v-model
的具体实现方式略有不同,但总体思路是将表单元素的值绑定到 Vue 实例的数据属性上,同时监听表单元素的输入事件,当用户输入时,更新 Vue 实例中的数据;当 Vue 实例中的数据发生变化时,更新表单元素的值。
2.不同表单元素的实现
1. input
元素(文本输入框)
对于 input
元素,v-model
会将 :value
绑定到 Vue 实例的数据属性上,同时监听 @input
事件。当用户在输入框中输入内容时,input
事件会被触发,在事件处理函数中更新 Vue 实例中的数据;当 Vue 实例中的数据发生变化时,会更新 input
元素的 value
属性。
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>v-model Input Example</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
</head>
<body>
<div id="app">
<!-- 等价于 <input :value="message" @input="message = $event.target.value"> -->
<input v-model="message">
<p>{{ message }}</p>
</div>
<script>
new Vue({
el: '#app',
data: {
message: ''
}
});
</script>
</body>
</html>
在上述代码中,v-model="message"
实际上等价于 :value="message" @input="message = $event.target.value"
。当用户在输入框中输入内容时,input
事件被触发,message
的值会被更新为输入框的当前值;当 message
的值在 Vue 实例中被修改时,输入框的 value
属性也会相应更新。
2. checkbox
元素(复选框)
对于单个 checkbox
元素,v-model
绑定的是一个布尔值,表示复选框是否被选中。当复选框被选中或取消选中时,会触发 change
事件,在事件处理函数中更新 Vue 实例中的布尔值;当布尔值发生变化时,会更新复选框的 checked
属性。
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>v-model Checkbox Example</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
</head>
<body>
<div id="app">
<!-- 等价于 <input type="checkbox" :checked="isChecked" @change="isChecked = $event.target.checked"> -->
<input type="checkbox" v-model="isChecked">
<p>{{ isChecked }}</p>
</div>
<script>
new Vue({
el: '#app',
data: {
isChecked: false
}
});
</script>
</body>
</html>
这里 v-model="isChecked"
等价于 :checked="isChecked" @change="isChecked = $event.target.checked"
。当复选框的选中状态改变时,isChecked
的值会相应更新;当 isChecked
的值在 Vue 实例中被修改时,复选框的 checked
属性也会更新。
3. radio
元素(单选框)
对于 radio
元素,v-model
绑定的是一个值,当某个单选框被选中时,会触发 change
事件,在事件处理函数中更新 Vue 实例中的值为该单选框的 value
属性值;当 Vue 实例中的值发生变化时,会根据值来选中对应的单选框。
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>v-model Radio Example</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
</head>
<body>
<div id="app">
<!-- 等价于 <input type="radio" :checked="selected === 'option1'" @change="selected = 'option1'"> -->
<input type="radio" v-model="selected" value="option1"> Option 1
<input type="radio" v-model="selected" value="option2"> Option 2
<p>{{ selected }}</p>
</div>
<script>
new Vue({
el: '#app',
data: {
selected: 'option1'
}
});
</script>
</body>
</html>
v-model="selected"
对于每个单选框分别等价于 :checked="selected === 'value'" @change="selected = 'value'"
。当某个单选框被选中时,selected
的值会更新为该单选框的 value
;当 selected
的值在 Vue 实例中被修改时,对应的单选框会被选中。
4. select
元素(下拉框)
对于 select
元素,v-model
绑定的是选中项的值。当选择不同的选项时,会触发 change
事件,在事件处理函数中更新 Vue 实例中的值为选中项的 value
属性值;当 Vue 实例中的值发生变化时,会根据值来选中对应的选项。
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>v-model Select Example</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
</head>
<body>
<div id="app">
<!-- 等价于 <select :value="selected" @change="selected = $event.target.value"> -->
<select v-model="selected">
<option value="option1">Option 1</option>
<option value="option2">Option 2</option>
</select>
<p>{{ selected }}</p>
</div>
<script>
new Vue({
el: '#app',
data: {
selected: 'option1'
}
});
</script>
</body>
</html>
v-model="selected"
等价于 :value="selected" @change="selected = $event.target.value"
。当选择不同的选项时,selected
的值会更新为选中项的 value
;当 selected
的值在 Vue 实例中被修改时,对应的选项会被选中。
总结
v-model
通过结合数据绑定和事件监听,实现了表单元素和 Vue 实例数据的双向同步。不同的表单元素使用不同的属性(如 value
、checked
等)和事件(如 input
、change
等)来实现这一功能。