# 表单输入绑定

可以用 v-model 指令在表单 <input>、<textarea> 及 <select> 元素上创建双向数据绑定。它会根据控件类型自动选取正确的方法来更新元素。 v-model 本质是语法糖。它负责监听用户的输入事件以更新数据,并对一些极端场景进行一些特殊处理。

v-model 会忽略所有表单元素的 value、checked、selected 特性的初始值而总是将 Vue 实例的数据作为数据来源。你应该通过 JavaScript 在组件的 data 选项中声明初始值。

v-model 在内部为不同的输入元素使用不同的属性并抛出不同的事件:

  • text 和 textarea 元素使用 value 属性和 input 事件;
  • checkbox 和 radio 使用 checked 属性和 change 事件;
  • select 字段将 value 作为 prop 并将 change 作为事件。

使用输入法输入中文时,v-model 不会在输入法组合文字过程中得到更新。如果想处理这个过程,需要使用 input 事件。

# 基础用法

# input 文本

<input v-model="message" placeholder="edit me">
<p>Message is: {{ message }}</p>

# textarea多行文本

<!-- 在文本区域插值无效 (<textarea>{{text}}</textarea>,需要使用v-model属性 -->
<span>Multiline message is:</span>
<p style="white-space: pre-line;">{{ message }}</p>
<br>
<textarea v-model="message" placeholder="add multiple lines"></textarea>

# checkbox 复选框

单个复选框,绑定布尔值

<input type="checkbox" id="checkbox" v-model="checked">
<label for="checkbox"> {{ checked }}</label>

多个复选框绑定到同一数组

<div id="app">
  <div>
    <input type="checkbox" id="apple" value="apple" v-model="checkedFruits">
    <label for="apple">Apple</label>
    <input type="checkbox" id="orange" value="orange" v-model="checkedFruits">
    <label for="orange">Orange</label>
    <input type="checkbox" id="banana" value="banana" v-model="checkedFruits">
    <label for="banana">Banana</label>
  </div>
  <p>已选择 : {{ checkedFruits.join(' / ') }}</p>
</div>
<script>
  var vm = new Vue({
    el: '#app',
    data: {
      checkedFruits: []
    }
  })
</script>

# radio单选

不是使用相同的name,而是使用v-model指向相同的变量

<div id="app">
  <div>
    <input type="radio" id="apple" value="apple" v-model="picked">
    <label for="apple">Apple</label>
    <input type="radio" id="orange" value="orange" v-model="picked">
    <label for="orange">Orange</label>
    <input type="radio" id="banana" value="banana" v-model="picked">
    <label for="banana">Banana</label>
  </div>
  <p>已选择 : {{ picked }}</p>
</div>
<script>
  var vm = new Vue({
    el: '#app',
    data: {
      picked: ''
    }
  })
</script>

# select 选择框

新增multiple属性时selected的值自动为数组

<div id="app">
  <select v-model="selected">
    <option disabled value="">请选择</option> <!--选择时按option不可选-->
    <option>A</option>
    <option>B</option>
    <option>C</option>
  </select>
  <p> 已选择: {{ selected }} </p>
</div>
<script>
  var vm = new Vue({
    el: '#app',
    data: {
      selected: ''
    }
  })
</script>

原生写法

var formObj = document.forms[0];
var fields = formObj.elements;
// 遍历fileds
switch(field.type) {
  case undefined: // 字符集
  case 'file': // 文件输入
  case 'submit': // 提交按钮
  case 'reset': // 重置按钮
  case 'button': // 自定义按钮
      // 非输入内容,break
      break;
  case 'select-multiple': // 多选,需要特殊处理
      var options = field.options;
      var selectArr = [];
      for (let j = 0; j < options.length; j++) {
          if (options[j].selected) {
              selectArr.push(options[j].value)
          }
      }
      contentArr.push(encodeURIComponent(field.name) + '=' + encodeURIComponent(selectArr.join(';')));
      break;
  default: // select, input等
      contentArr.push(encodeURIComponent(field.name) + '=' + encodeURIComponent(field.value))
}

# v-for动态渲染select

<select v-model="youSelected">
  <option disabled value="">请选择</option> <!--选择时按option不可选-->
  <option v-for="item in options" :value="item.value"> {{ item.text }} </option>
</select>
<p> 已选择: {{ youSelected }} </p>
<script>
  data: {
    youSelected: '',
    options: [
      {text: '1', value: 'a'}, 
      {text: '2', value: 'b'}, 
      {text: '3', value: 'c'}, 
    ]
  }
</script>

# 值绑定

# 复选框的true和false可以指定值

<input
  type="checkbox"
  v-model="toggle"
  true-value="yes"
  false-value="no"
>
// 选中时: 
vm.toggle === 'yes'
// 未选中时
vm.toggle === 'no'

# value可以是动态的

<input type="radio" v-model="pick" v-bind:value="a">
// 当选中时
vm.pick === vm.a

# option的值可以是对象

<select v-model="selected">
    <!-- 内联对象字面量 -->
  <option v-bind:value="{ number: 123 }">123</option>
</select>
// 当选中时
typeof vm.selected // => 'object'
vm.selected.number // => 123

# v-model修饰符

  • .lazy change才触发同步更新,而不是默认input事件
  • .number 自动将用户的输入值转为数值类型
  • .trim 自动过滤首尾空格
<!-- 在“change”时而非“input”时更新 -->
<input v-model.lazy="msg" >

<input v-model.number="age" type="number">

<input v-model.trim="msg">

上次更新: 2020/10/29 22:59:19