首页 > 编程笔记 > JavaScript笔记
Vue v-model双向绑定表单数据详解
对于 Vue 来说,使用 v-bind 并不能解决表单域对象双向绑定的需求,为此 Vue 提供了 v-model 指令。
MVVM 模式最重要的一个特性,可以说实现了数据的双向绑定,而 Vue 作为一个 MVVM 框架,肯定也实现了数据的双向绑定。在 Vue 中使用内置的 v-model 指令完成数据在 View 与 Model 间的双向绑定。
可以用 v-model 指令在表单的 <input>、<textarea> 及 <select> 元素上创建双向数据绑定。它会根据控件类型自动选取正确的方法来更新元素。尽管有些神奇,但 v-model 本质上不过是语法糖。它负责监听用户的输入事件以更新数据,并对一些极端场景进行特殊处理。
v-model 会忽略所有表单元素的 value、checked、selected 特性的初始值,而总是将 Vue 实例的数据作为数据来源。这里应该通过 JavaScript 在组件的 data 选项中声明初始值。
【实例一】绑定单行文本输入框
图 1 变更后效果
图 2 绑定多行文本输入框
图 3 选中效果
将多个复选框绑定到同一个数组,被选中的复选框添加到数组中。示例代码如下:
图 4 绑定多个复选框
例如,多个单选框绑定到同一个数组,被选中的单选框添加到数组中。
图 5 绑定单选按钮
图 6 绑定单选框
如果 v-model 表达式的初始值未能匹配任何选项,<select> 元素将被渲染为“未选中”状态。
图 7 绑定多选框
例如:
图 8 v-for渲染的动态选项
例如:
图 9 选择复选框的状态
例如:
图 10 单选框选中效果
图 11 动态绑定选择框的选项
对于数据的绑定,无论是使用插值表达式({{}})还是 v-text 指令,对于数据间的交互都是单向的,只能将 Vue 实例中的值传递给页面,页面对数据值的任何操作都无法传递给 model。所谓双向绑定,就是无论是通过 input 还是通过 Vue 对象,都能修改绑定的数据对象的值。
MVVM 模式最重要的一个特性,可以说实现了数据的双向绑定,而 Vue 作为一个 MVVM 框架,肯定也实现了数据的双向绑定。在 Vue 中使用内置的 v-model 指令完成数据在 View 与 Model 间的双向绑定。
可以用 v-model 指令在表单的 <input>、<textarea> 及 <select> 元素上创建双向数据绑定。它会根据控件类型自动选取正确的方法来更新元素。尽管有些神奇,但 v-model 本质上不过是语法糖。它负责监听用户的输入事件以更新数据,并对一些极端场景进行特殊处理。
v-model 会忽略所有表单元素的 value、checked、selected 特性的初始值,而总是将 Vue 实例的数据作为数据来源。这里应该通过 JavaScript 在组件的 data 选项中声明初始值。
单行文本输入框
下面讲解常见的单行文本输入框的数据双向绑定。【实例一】绑定单行文本输入框
<input type="text" v-model="message" value="hello world"> <p>{{message}}</p> </div> <!--引入Vue文件--> <script src="https://unpkg.com/vue@next"></script> <script> //创建一个应用程序实例 const vm= Vue.createApp({ //该函数返回数据对象 data(){ return{ message:"红罗袖里分明见" } } //在指定的DOM元素上装载应用程序实例的根组件 }).mount('#app'); </script>在 Chrome 浏览器中运行程序,在输入框中输入“白玉盘中看却无”,可以看到下面的内容也发生了变化,如下图所示:
图 1 变更后效果
多行文本输入框
在多行文本输入框 textarea 标签中绑定 message 属性,代码如下:<div id="app"> <p>{{message}}</p> <textarea v-model="message"></textarea> </div> <!--引入Vue文件--> <script src="https://unpkg.com/vue@next"></script> <script> //创建一个应用程序实例 const vm= Vue.createApp({ //该函数返回数据对象 data(){ return{ message:"轻衣软履步江沙" } } //在指定的DOM元素上装载应用程序实例的根组件 }).mount('#app'); </script>在 Chrome 浏览器中运行程序,在textarea标签中输入多行文本,效果如下图所示。
图 2 绑定多行文本输入框
复选框
复选框单独使用时,绑定的是布尔值,选中则值为 true,未选中则值为 false。示例代码如下。<div id="app"> <input type="checkbox" id="checkbox" v-model="checked"> <label for="checkbox">{{ checked }}</label> </div> <!--引入Vue文件--> <script src="https://unpkg.com/vue@next"></script> <script> //创建一个应用程序实例 const vm= Vue.createApp({ //该函数返回数据对象 data(){ return{ //默认值为false checked:false } } //在指定的DOM元素上装载应用程序实例的根组件 }).mount('#app'); </script>在 Chrome 浏览器中运行程序,当选中复选框后,checked 的值变为 true,效果如下图所示。
图 3 选中效果
将多个复选框绑定到同一个数组,被选中的复选框添加到数组中。示例代码如下:
<div id="app"> <p>选择需要采购的商品:</p> <input type="checkbox" id="name1" value="洗衣机" v-model="checkedNames"> <label for="name1">洗衣机</label> <input type="checkbox" id="name2" value="冰箱" v-model="checkedNames"> <label for="name2">冰箱</label> <input type="checkbox" id="name3" value="电视机" v-model="checkedNames"> <label for="name3">电视机</label> <input type="checkbox" id="name4" value="空调" v-model="checkedNames"> <label for="name4">空调</label> <p><span>选中的商品:{{ checkedNames }}</span></p> </div> <!--引入Vue文件--> <script src="https://unpkg.com/vue@next"></script> <script> //创建一个应用程序实例 const vm= Vue.createApp({ //该函数返回数据对象 data(){ return{ checkedNames: [] //定义空数组 } } //在指定的DOM元素上装载应用程序实例的根组件 }).mount('#app'); </script>在 Chrome 浏览器中运行程序,选择多个复选框,选择的内容显示在数组中,如下图所示。
图 4 绑定多个复选框
单选按钮
单选按钮一般都有多个条件可供选择,既然是单选按钮,自然希望实现互斥效果,这个效果可以使用 v-model 指令配合单选框的 value 来实现。例如,多个单选框绑定到同一个数组,被选中的单选框添加到数组中。
<div id="app"> <h3>请选择本次采购的商品(单选题)</h3> <input type="radio" id="one" value="A" v-model="picked"> <label for="one">A.洗衣机</label><br/> <input type="radio" id="two" value="B" v-model="picked"> <label for="two">B.冰箱</label><br/> <input type="radio" id="three" value="C" v-model="picked"> <label for="three">C.空调</label><br/> <input type="radio" id="four" value="D" v-model="picked"> <label for="four">D. 电视机</label> <p><span>选择: {{ picked }}</span></p> </div> <!--引入Vue文件--> <script src="https://unpkg.com/vue@next"></script> <script> //创建一个应用程序实例 const vm= Vue.createApp({ //该函数返回数据对象 data(){ return{ picked: '' } } //在指定的DOM元素上装载应用程序实例的根组件 }).mount('#app'); </script>在 Chrome 浏览器中运行程序,单击“D.电视机”单选按钮,效果如下图所示。
图 5 绑定单选按钮
选择框
接下来详细讲述如何绑定单选框、多选框和用 v-for 渲染的动态选项。1) 单选框
不需要为 <select> 标签添加任何属性,即可实现单选。示例如下。<div id="app"> <h3>选择喜欢的课程</h3> <select v-model="selected"> <option disabled value="">选择喜欢的课程</option> <option>Python开发班</option> <option>Java开发班</option> <option>前端开发班</option> </select> <span>选择的课程: {{ selected }}</span> </div> <!--引入Vue文件--> <script src="https://unpkg.com/vue@next"></script> <script> //创建一个应用程序实例 const vm= Vue.createApp({ //该函数返回数据对象 data(){ return{ selected: ' ' } } //在指定的DOM元素上装载应用程序实例的根组件 }).mount('#app'); </script>在 Chrome 浏览器中运行程序,在下拉选项中选择“Java开发班”,选择结果中也变成了“Java开发班”,效果如下图所示。
图 6 绑定单选框
如果 v-model 表达式的初始值未能匹配任何选项,<select> 元素将被渲染为“未选中”状态。
2) 多选框(绑定到一个数组)
为 <select> 标签添加 multiple 属性,即可实现多选。示例如下。<div id="app"> <h3>请选择您喜欢的课程</h3> <select v-model="selected" multiple style="height: 100px"> <option disabled value="">可以选择的课程如下</option> <option>Java开发班</option> <option>Python开发班</option> <option>前端开发班</option> <option>PHP开发班</option> </select><br/> <span>选择的课程: {{ selected }}</span> </div> <!--引入Vue文件--> <script src="https://unpkg.com/vue@next"></script> <script> //创建一个应用程序实例 const vm= Vue.createApp({ //该函数返回数据对象 data(){ return{ selected: [] } } //在指定的DOM元素上装载应用程序实例的根组件 }).mount('#app'); </script>在 Chrome 浏览器中运行程序,按住 Ctrl 键可以选择多个选项,效果如下图所示。
图 7 绑定多选框
3) 用v-for渲染的动态选项
在实际应用场景中,<select> 标签中的 <option> 一般是通过 v-for 指令动态输出的,其中每一项的 value 或 text 都可以使用 v-bind 动态输出。例如:
<div id="app"> <h3>请选择您喜欢的课程</h3> <select v-model="selected"> <option v-for="option in options" v-bind:value="option.value">{{option.text}}</option> </select> <span>选择的课程: {{ selected }}</span> </div> <!--引入Vue文件--> <script src="https://unpkg.com/vue@next"></script> <script> //创建一个应用程序实例 const vm = Vue.createApp({ //该函数返回数据对象 data(){ return{ selected: [], options:[ { text: '课程1', value: 'Java开发班' }, { text: '课程2', value: 'Python开发班' }, { text: '课程3', value: '前端开发班' } ] } } }).mount('#app'); </script>在 Chrome 浏览器中运行程序,然后在选择框中选择“课程2”,将会显示它对应的 value 值,效果如下图所示。
图 8 v-for渲染的动态选项
值绑定
对于单选按钮、复选框及选择框的选项,v-model 绑定的值通常是静态字符串(对于复选框也可以是布尔值)。但是,有时可能想把值绑定到Vue实例的一个动态属性上,这种情况可以用 v-bind 实现,并且这个属性的值可以不是字符串。1) 复选框
在下面的示例中,true-value 和 false-value 的特性并不会影响输入控件的 value 特性,因为浏览器在提交表单时并不会包含未被选中的复选框。如果要确保表单中这两个值中的一个能够被提交,比如“yes”或“no”,则需要换用单选按钮。例如:
<div id="app"> <input type="checkbox" v-model="toggle" true-value="yes" false-value="no"> <span>{{toggle}}</span> </div> <!--引入Vue文件--> <script src="https://unpkg.com/vue@next"></script> <script> //创建一个应用程序实例 const vm = Vue.createApp({ //该函数返回数据对象 data(){ return{ toggle:'false' } } }).mount('#app'); </script>在 Chrome 浏览器中运行程序,选择复选框的状态效果如下图所示。
图 9 选择复选框的状态
2) 单选框
首先为单选按钮绑定一个属性 date,定义属性值为“洗衣机”;然后使用 v-model 指令为单选按钮绑定 pick 属性,当单选按钮被选中后,pick 的值等于 a 的属性值。例如:
<div id="app"> <input type="radio" v-model="pick" v-bind:value="date"> <span>{{ pick}}</span> </div> <!--引入Vue文件--> <script src="https://unpkg.com/vue@next"></script> <script> //创建一个应用程序实例 const vm = Vue.createApp({ //该函数返回数据对象 data(){ return{ date:'洗衣机 ', pick:'未选择' } } }).mount('#app'); </script>在 Chrome 浏览器中运行程序,选中“洗衣机”单选按钮,将显示其 value 值,效果如下图所示。
图 10 单选框选中效果
3) 选择框的选项
在下面的示例中,定义了 4 个 option 选项,并使用 v-bind 进行绑定。<div id="app"> <select v-model="selected" multiple> <option v-bind:value="{ number: 100 }">A</option> <option v-bind:value="{ number: 200 }">B</option> <option v-bind:value="{ number: 300 }">C</option> <option v-bind:value="{ number: 400 }">D</option> </select> <p><span>{{ selected }}</span></p> </div> <!--引入Vue文件--> <script src="https://unpkg.com/vue@next"></script> <script> //创建一个应用程序实例 const vm = Vue.createApp({ //该函数返回数据对象 data(){ return{ selected:[] } } }).mount('#app'); </script>在 Chrome 浏览器中运行程序,选中 C 和 D 选项,在 p 标签中将显示相应的 number 值,如下图所示。
图 11 动态绑定选择框的选项