表单元素的双向绑定指令v-model

目录

  • v-model的基础用法
  • v-model双向绑定实现的原理
  • v-model绑定值的输出类型(字符串、数组、布尔值、自定义)
  • v-model修饰符:.lazy .number .trim

VUE为表单元素交互提供了一个能实现双向数据绑定的指令:v-model

v-model基础用法

  1. <input type="text" v-model="value" />

v-model双向绑定实现的原理

点击查看DEMO:v-model双向绑定实现的原理

我们先理解下双向绑定中“双向”指的什么?

可以理解为信息在逻辑层和视图层两个方向的互相传递。

  1. ui <=> js

我们前面总结过的指令,都是将逻辑层数据的变化传到视图层更新显示,这是单向数据绑定。比如对于表单的输入框,我们需要向它提供初始值,或通过按钮控制改变它的值。

  1. <div id="example_1">
  2. <input type="number" v-bind:value="value"/>
  3. <button @click="changeValue">按钮加10</button>
  4. <p>{{ value }}</p>
  5. </div>
  1. new Vue({
  2. el: "#example_1",
  3. data: {
  4. value: 0
  5. },
  6. methods: {
  7. changeValue() {
  8. this.value += 10
  9. }
  10. }
  11. })

上面这个例子,逻辑层中的值value改变了,都会通过v-bind指令同步到输入框中显示出来。这是逻辑层向视图层的单向传递。但是如果我们直接在输入框中改变值,value的值并不会显示改变。也就是说在视图层输入框中值的改变没有通知到逻辑层对应的value改变。

如果要实现这点,我们就需要利用到表单元素自身的事件,如input输入框元素的input事件。能监控到输入框内容的改变,从而处理相应的逻辑。对于这个例子,我们需要在input事件处理函数中将当前输入值赋给value。利用之前学过的VUE中事件绑定指令v-on实现:

  1. <div id="example_2">
  2. <input type="number" v-bind:value="value" v-on:input="updateValue" />
  3. <p>{{ value }}</p>
  4. </div>
  1. new Vue({
  2. el: "#example_2",
  3. data: {
  4. value: 0
  5. },
  6. methods: {
  7. updateValue(e) {
  8. this.value = e.target.value
  9. }
  10. }
  11. })

这样就实现了视图层和逻辑层的双向绑定。但是像上面这种写法,一个input元素要绑定v-bind指令,同时还要绑定v-on指令,不够优雅。

所以VUE直接用一个指令v-model来绑定,替代上面的写法实现同一种功能,这就是v-model的双向绑定。

  1. <input type="number" v-bind:value="value" v-on:input="updateValue" />
  2. <input type="number" v-model="value" />

上面例子,点击按钮会让逻辑层data中的value值加10,这个改变会同步到视图层,显示在input输入框中。同时,直接在视图层input输入框中输入内容也会使逻辑层中value值改变。这就是v-model的双向绑定。

具体双向绑定实现的原理,其时很简单,v-model指令不过是个语法糖而已,v-model 绑定表单元素,会使用该表单元素对应的属性和事件,来实现双向绑定。

但是,VUE内部会智能的根据不同的表单元素,来选用该元素对应的属性和事件来实现v-model双向绑定,并且绑定的值输出类型也会不同。

  • text 和 textarea 元素使用 value 属性和 input 事件,值为字符串文本;
  • checkbox 和 radio 使用 checked 属性和 change 事件,checkbox为单个时绑定值为布尔值,多选为数组,radio绑定依value值类型;
  • select 字段将 value 作为 prop ,并将 change 作为事件。多选时为数组

v-model绑定值的输出类型(字符串、数组、布尔值、自定义)

点击查看DEMO:v-model绑定值的输出类型(字符串、数组、布尔值、自定义)

  1. <div id="example_4">
  2. <!-- 当选中时,`picked` 为 `value`的值 -->
  3. <input type="radio" v-model="picked" value="a">
  4. <input type="radio" v-model="picked" value="b">
  5. <span>{{ picked }}</span><br/>
  6. <!-- `toggle`类型为非Array时,会忽略value值,直接赋值为 true 或 false 。但是当为数组时,会将value值添加进去-->
  7. <input type="checkbox" value="1" v-model="toggle">
  8. <span>{{ toggle }}</span><br/>
  9. <!-- `multiChecked`必须为Array类型时才能将值添加到数组,否则为全选true / false -->
  10. <input type="checkbox" value="a" v-model="multiChecked">
  11. <input type="checkbox" value="b" v-model="multiChecked">
  12. <input type="checkbox" value="c" v-model="multiChecked">
  13. <span>{{ multiChecked }}</span><br/>
  14. <!-- -->
  15. <select v-model="selected">
  16. <option disabled value="">请选择</option>
  17. <option>A</option><!-- 当不存在value特性时,会取内容A作为值 -->
  18. <option value="b">B</option>
  19. <option value="c">C</option>
  20. </select>
  21. <span>{{ selected }}</span><br/>
  22. </div>
  1. new Vue({
  2. el: "#example_4",
  3. data: {
  4. picked: '',
  5. toggle: '',
  6. // toggle: [],
  7. multiChecked: [],
  8. // multiChecked: '',
  9. selected: '',
  10. toggle_self: '',
  11. selected_self: '',
  12. }
  13. })

v-model 绑定的值通常是静态字符串 (对于复选框也可以是布尔值),但是有时我们可能想把值绑定到一个自定义数据或动态数据上,这时可以用 v-bind 实现,并且v-bind绑定的这个属性的值可以不是字符串。

  1. <!-- 自定义输出值,选中后toggle_self为 yes 或 no -->
  2. <input
  3. type="checkbox"
  4. v-model="toggle_self"
  5. true-value="yes"
  6. false-value="no"
  7. >
  8. <span>{{ toggle_self }}</span><br/>
  9. <!-- 自定义输出值,选中后elected_self为对象{number:123} -->
  10. <select v-model="selected_self">
  11. <!-- 内联对象字面量 -->
  12. <option v-bind:value="{ number: 123 }">123</option>
  13. </select>
  14. <span>{{ selected_self }}</span>
  15. <span>{{ selected_self.number }}</span><br/>

v-model修饰符:.lazy .number .trim

点击查看DEMO:v-model修饰符

.number

v-model绑定的值一般情况下都是字符串形式,即使input[type="number"]时。我们可以验证一下:

  1. <!-- 先触发输入框,再点击按钮,发现内容为字符串拼接形式,而不是相加结果 -->
  2. <div id="example_3">
  3. <input type="number" v-model:value="value"/>
  4. <button @click="changeValue">按钮加10</button>
  5. <p>{{ value }}</p>
  6. </div>
  1. new Vue({
  2. el: "#example_3",
  3. data: {
  4. value: 0
  5. },
  6. methods: {
  7. changeValue() {
  8. this.value += 10
  9. }
  10. }
  11. })
  1. 210101010

如果要实现点击按钮是数值相加结果,我们可以在按钮事件处理函数中对value类型进行处理,如:

  1. this.value = Number(this.value) + 10
  2. this.value = this.value * 1 + 10

但是Vue提供了更为简单的方法,使用.number修饰符

  1. <input type="number" v-model:value.number="value"/>

.lazy

在默认情况下,v-model 在每次 input 事件触发后将输入框的值与数据进行同步,表现为实时触发。你可以添加 .lazy 修饰符,从而转变为使用 change 事件进行同步,表现为输入框失去焦点后触发。

  1. <!-- 在“change”时而非“input”时更新 -->
  2. <input type="number" v-model:value.lazy="value_lazy"/>
  1. oninput 事件在元素值发生变化是立即触发, onchange 在元素失去焦点时触发。

.trim

对于inputtextarea表单元素,如果要自动过滤用户输入的首尾空白字符,可以给 v-model 添加 trim 修饰符。

  1. <input type="text" v-model:value.trim="value_trim"/>

vue-learning:9-template-v-model的更多相关文章

  1. vue报错:Component template should contain exactly one root element. If you are using v-if on multiple elements, use v-else-if to chain them instead.

    在.vue文件中引入了 element-ui 的 table 和 pagination 组件后,报错:Component template should contain exactly one roo ...

  2. 小白学习VUE第二课:环境搭建 VUE Node.js VSCode template模板

    环境搭建 VUE Node.js VSCode template模板: 首先安装node:http://www.runoob.com/nodejs/nodejs-install-setup.html ...

  3. Vue.js:轻量高效的前端组件化方案

    转发一篇尤老师对vue.js的介绍,了解vue.js的来龙去脉.不过现在已经是2.0了,也有添加一些新的东西,当然有些东西也改了. Vue.js:轻量高效的前端组件化方案 Vue.js 是我在2014 ...

  4. Vue系列:如何将百度地图包装成Vue的组件

    主要分解为如下步骤: (1)在html文件中引入百度地图, <script type="text/javascript" src="http://api.map.b ...

  5. Vue.js:轻量高效的前端组件化方案(转载)

    摘要:Vue.js通过简洁的API提供高效的数据绑定和灵活的组件系统.在前端纷繁复杂的生态中,Vue.js有幸受到一定程度的关注,目前在GitHub上已经有5000+的star.本文将从各方面对Vue ...

  6. 【转】Vue.js:轻量高效的前端组件化方案

    摘要:Vue.js通过简洁的API提供高效的数据绑定和灵活的组件系统.在前端纷繁复杂的生态中,Vue.js有幸受到一定程度的关注,目前在GitHub上已经有5000+的star.本文将从各方面对Vue ...

  7. Deep learning:五十一(CNN的反向求导及练习)

    前言: CNN作为DL中最成功的模型之一,有必要对其更进一步研究它.虽然在前面的博文Stacked CNN简单介绍中有大概介绍过CNN的使用,不过那是有个前提的:CNN中的参数必须已提前学习好.而本文 ...

  8. Deep learning:四十六(DropConnect简单理解)

    和maxout(maxout简单理解)一样,DropConnect也是在ICML2013上发表的,同样也是为了提高Deep Network的泛化能力的,两者都号称是对Dropout(Dropout简单 ...

  9. 转载 Deep learning:六(regularized logistic回归练习)

    前言: 在上一讲Deep learning:五(regularized线性回归练习)中已经介绍了regularization项在线性回归问题中的应用,这节主要是练习regularization项在lo ...

  10. 组件嵌套时报:Component template should contain exactly one root element. If you are using v-if on multiple elements, use v-else-if to chain them instead.

    在组件嵌套的过程中,报了一个错误: 这里报错的原因是:vue的组件(模板)只能有一个根节点,即.vue文件中的<template>标签下只能有一个子元素. 因此,建议大家在写.vue组件的 ...

随机推荐

  1. 关于element-ui的弹框问题

    el-dialog获取数据. el-dialog加载到页面中的时候,其实已经加载好了.只是默认隐藏了. 第一次点击的时候弹出,为何拿不到数据?之后再次操作就一点问题都没有了.

  2. hdu1421 dp

    用dp[i][j]表示放了i件物品,j对时的最小值. dp[i-2][j-1]表示取当前的 dp[i-1][j]表示不取当前的. #include<stdio.h> #include< ...

  3. GCD使用经验与技巧浅谈

    前言 GCD(Grand Central Dispatch)可以说是Mac.iOS开发中的一大“利器”,本文就总结一些有关使用GCD的经验与技巧. dispatch_once_t必须是全局或stati ...

  4. select引起的服务端程序崩溃问题

    现象: 某个线上的服务最近频繁崩溃.该服务使用C++编写,是个网络服务端程序.作为TCP服务端,接收和转发客户端发来的消息,并给客户端发送消息.该服务跑在CentOS上,8G内存.线上环境中,与客户端 ...

  5. Android 系统字体和颜色样式

    Android 字体和颜色 对于能够显示文字的控件(如TextView EditText RadioButton Button CheckBox Chronometer等等),你有时需要控制字体的大小 ...

  6. VelocityTracker监控速度!!!

    用来追踪触摸事件(flinging事件和其他手势事件)的速率.用obtain()函数来获得类的实例,用addMovement(MotionEvent)函数将motion event加入到Velocit ...

  7. ELK练习

    1.ELK练习 PUT s3/_doc/ { "mappings" : { "doc" : { "properties" : { " ...

  8. jmeter循环取消今天所有的订单

    结构 1.首先,添加JDBC Connection Configuration 2.其次添加JDBC request 添加循环控制器 循环控制器下方添加计数器 ${__V(reservationID_ ...

  9. @bzoj - 3750@ [POI2015] Pieczęć

    目录 @description@ @solution@ @accepted code@ @details@ @description@ 一张 n*m 的方格纸,有些格子需要印成黑色,剩下的格子需要保留 ...

  10. behavior planning——11 create a cost function speed penalty

    A  key part of getting transitions to happen when we want  them to is the design of reasonable cost ...