第5章 Vue表单控件绑定

在Web应用中,我们经常会使用表单向服   务端提交一些数据,而通常也会在表单项中绑定一些如input、change等事件对用户输入的数据进行检验、更新等操作。在Vue.js中,我们可以使用v-model指令同步用户输入的数据到Vue实例data属性中,同时会对radion、checkbox、select等原生表单组件提供一些语法糖使表单操作更加容易。  

5.1 基本用法:使用v-model更新表单控件

①text

设置v-model为name,代码如下:

<span>welcome {{name}} join RLW </span>

<input type="text" v-model="name" placeholder="join RLW">

当用户操作文本时,vm.name会自动更新为用户输入的值,同时span的内容也会随之改变。

②checkbox

<input type="checkbox" id="checkbox" v-model="checked"

<label for="checkbox">{{checked}}</label>

当用户勾选了checkbox时,vm.checked=true,否则vm.checked=false,label中的值也会随之改变。  

大多数的时候我们使用的都是多个复选框,即一个复选框组。此时,被选中的值将会放在一个数组中。

<input type="checkbox" id="flash" value="flash" v-model="bizLines">

<label for="flash">快车</label>

<input type="checkbox" id="premium" value="premium" v-model="bizLines">

<label for="premium">专车</label>

<input type="checkbox" id="bus" value="bus" v-model="bizLines">

<label for="bus">巴士</label>

<br>

<span>Checked lines:{{ bizLines | json }}</span>

new Vue({

   el:'...',

   data:{

       bizLines:[ ]   

   }

})

③radio

当单选按钮被选中时,v-model中的变量值会被赋值为对应的value值。

<input type="radio" id="flash" value="flash" v-model="bizLine">  

<label for="flash">快车</label>

<br>

<input type="radio" id="bus" value="bus" v-model="bizLine">

<label for="bus">巴士</label> 

<br>

<span>Picked:{{ bizLIne }}</span>

④select

因为select控件分为单选和多选,所以v-model在select控件的单选和多选上会有不同的表现。

当被选中的option有value属性时,vm.selected为对应的option的value的值。否则为对应option的text的值。

对于多选select控件,被选中的值会放入一个数组中。

我们也可以通过v-for指令来动态生成option。

5.2 值绑定

在通常情况下,对于radio、checkbox、select组件,通过v-model绑定的值都是字符串,checkbox除外,checkbox可能是布尔值。  

<!-- 勾选时`picked`的值是字符串 a -->

<input type="radio" v-model="picked" value="a">    

<!-- 勾选时`toggle`的值是布尔值true,否则是布尔值false -->

<input type="checkbox" v-model="toggle"> 

<!-- 勾选时`selected`的值是字符串 abc -->

<select v-model="selected">

   <option value="abc">ABC</option>

</select> 

有时候我们会有动态绑定Vue.js实例属性的需求,这时可以使用v-bind来实现这个需求。通过v-bind来代替直接使用value属性,我们还可以绑定非字符串的值,如数值、对象、数组等。

①checkbox

<input type="checkbox" v-model="toggle" :true-value="a"

                                                                   :false-value="b">

勾选checkbox时,vm.toggle == vm.a

未勾选checkbox时,vmtoggle == vm.b

注: :true-value 和 :false-value 只适合同一个checkbox组只有一个checkbox的情况。如果有多个checkbox,请使用:value进行值绑定。

<input type="checkbox" id="flash" :value-"flash" v-model="bizLines">

<label for="flash">{{ flash.name }}</label>

<input type="checkbox" id="premium" :value="premium" v-model="bizLines">

<label for="premium">{{ premium.name }}</label>

<input type="checkbox" id="bus" :value="bus" v-model="bizLines">

<label for="bus">{{ bus.name }}</label>

<br>

<span>Checked bizLines:{{ bizLines | json }}</span>

new Vue({

  el:'...',

  data:{

     flash:{name:'快车'},

     premium:{name:'专车'},

     bus:{name:'巴士'},

     bizLines:[ ]

  }

})

②radio

<input type="radio" v-model="pick" :value="a">

勾选radio时,vm.pick === vm.a

③select

<select v-model="selected">

  <option :value="{ number:123 }">123</option>

</select>

用户勾选时,vm.selected === {number:123}

5.3 v-model修饰指令

v-model用来在视图与Model之间同步数据,但是有时候我们需要控制同步发生的时机,或者在数据同步到Model之前将数据转换为Number类型。我们可以再v-model指令所在的form控件上添加相应的修饰指令来实现这个需求。  

①lazy

在默认情况下,v-model在input事件中同步输入框的值与数据,可以添加一个lazy特性,从而改到在change事件中去同步。

<input v-model="msg" lazy><br/>

{{msg}}

②debounce

设置一个最小的延时,在每次敲击之后延时同步输入框的值到Model中。如果每次更新都要进行高耗操作(列如,在输入提示中AJAX请求)时,它较为有用。

<input v-model="msg" debounce="500">    

用户输入完毕500ms后,vm.msg才会被更新。

注:该指令是用来延迟同步用户输入的数据到Model中,并不会延迟用户输入事件执行。所以如果想要获取变化后的数据,我们应该用vm.$watch()来监听msg的变化,而不是在事件中获取最新数据。要想延迟DOM事件的执行,请参阅过滤器章节debounce过滤器。

③number

当传给后端的字段类型必须是数值的时候,我们可以在v-model所在控件上使用number指令,该指令会在用户输入被同步到Model中时将其转换为数值类型,如果转换结果为NaN,则对应的Model值还是用户输入的原始值。

<input v-model="age" number>

5.4 修饰指令原理

①lazy源码解析

所有的表单控件都绑定change,只是在不设置lazy时,默认绑定input。源码定义如下:

<!-- 源码目录: src/directives/public/model/text.js -->

var lazy = this.params.lazy

//...

this.on('change', this.rawListener)

if (!lazy){

  this.on('input',this.listener)

}

②debounce源码解析

其实debounce和filter中的debounce原理相似,都是用的同一个函数,核心都是setTimeout,只是debounce没有默认的wait值。

<!-- 源码目录:src/directives/publice/model/text.js -->

③number源码解析

调用util里面的toNumber方法。

<!-- 源码目录:src/directives/public/model/text.js -->

import {

  toNumber

} from '../../../util/index'

var number = this.params.number

//...

this.listener = this.rawListener = function () {

  if (composing || !self._bound){

     return

  }

  var val = number || isRange ? toNumber(el.value) : el.value

  self.set(val)

  //...

}

<!-- 源码目录:src/util/lang.js -->

export function toNumber (value) {

  if (typeof value !== 'string'){

     return value

  } else {

     var parsed = Number(value)

     return isNaN(parsed) ? value : parsed

  }

}

原文地址:https://www.cnblogs.com/goforxiaobo/p/12502748.html