v-model 双向数据绑定

v-model,其作用是:在输入表单控件或者自定义输入组件上创建双向数据绑定


输入表单控件的双向数据绑定

使用 v-model 在不同的表单输入元素上创建双向数据绑定,它会根据控件类型自动选取正确的方法来更新元素。

// HTML
   <div>{{msg}}</div>
   <input type="text" v-model="msg">

// JS
   data(){
      return {
         msg:'HelloWorld'
      }
   }

需要注意的是,v-model 会忽略所有表单元素的 valuecheckedselected特性的初始值,而总是将 Vue 实例的数据作为数据来源。所以,应该在 Vue 实例的 data选项中声明初始值

<input type="text" v-model='msg' value='不生效的的内容'>  // value 属性不生效

尽管有些神奇,但 v-model 本质上不过是语法糖:它负责监听用户的输入事件以更新数据,并对以下极端场景作出特殊处理。

为什么说 v-model 是一个语法糖 ?其实现方式是:在内部为不同的输入元素使用不同的属性并抛出不同的事件:

  • text 和 textarea 元素,使用 value 属性和 input 事件
# HTML

<p>{{show}}</p>

// 输入框
<input type="text" v-model="show" placeholder="请输入你想要搜索的内容">
// 多行文本_ 说明:在文本区域插值 (<textarea>{{text}}</textarea>) 并不会生效,应该用 v-model来代替
<textarea v-model="show"></textarea>
# JS
data(){
    return{
        show:''
    }
}
  • radio 和 checkbox,使用 checked 属性和 change 事件
# 单选框
// HTML
{{checked}}    // 点击后,获取单选框的value值
<form action="">
	<input type="radio" value='first' v-model="checked">
	<input type="radio" value='second' v-model="checked">
</form>

// JS
data(){
	return{
		checked:''
	}
}
# 复选框

## 单个复选框,绑定到布尔值(false,未选中状态;true,选中状态)
// HTML
{{checked}}	// false	
<form action="">
	<input type="checkbox" value='first' v-model="checked">
</form>
// JS
data(){
	return{
		checked:false
	}
}

## 多个复选框,绑定到同一个数组(数组元素为选中的元素的value值)
// HTML
{{checked}}		// [ "first", "second" ]
<form action="">
	<input type="checkbox" value='first' v-model="checked">
	<input type="checkbox" value='second' v-model="checked">
</form>
// JS
data(){
	return{
		checked:[]
	}
}
  • select 字段,将 value 作为 prop ,并将 change 作为事件
# 单选时,绑定一个空字符串

// HTML
{{checked}}	 // 单选,A
<form action="">
	<select name="" id="" v-model="checked">
		<option value="" selected disabled>请选择:</option>
		<option value="A">A</option>
		<option value="B">B</option>
		<option value="C">C</option>
	</select>
</form>
// JS
data(){
	return{
		checked:''
	}
}

# 多选时,绑定为一个数组

// HTML
{{checked}}	  // 按住多选,[ "A", "B", "C" ]
<form action="">
	<select name="" id="" v-model="checked" multiple>
		<option value="" disabled>请选择:</option>
		<option value="A">A</option>
		<option value="B">B</option>
		<option value="C">C</option>
	</select>
</form>
// JS
data(){
	return{
		checked:[]
	}
}

[ 小知识点 ] 如果 v-model表达式的初始值未能匹配任何选项,<select>元素将被渲染为“未选中”状态。

在 iOS 中,这会使用户无法选择第一个选项。因为这样的情况下,iOS 不会触发 change 事件。

因此,更推荐像上面这样提供一个值为空的禁用选项。


[ 值绑定 ] 单选按钮,复选框及选择框的选项,v-model绑定的值通常是静态字符串( 复选框,也可以是布尔值 )。

但,如果想把值绑定到 Vue 实例的一个动态属性上,这时可以用 v-bind实现,并且这个属性的值可以不是字符串。

  • radio
// HTML
    <div>{{pick}}</div>
    <input type="radio" v-model="pick" :value="msg">
    <!-- 当选中的时候,vm.pick === vm.msg -->

// JS
  data(){
    return {
      pick:'',
      msg:"HelloWorld",
    }
  }
  • checkbox

true-valuefalse-value特性并不会影响输入控件的 value特性,因为浏览器在提交表单时并不会包含未被选中的复选框。如果要确保表单中这两个值中的一个能够被提交,(比如“yes”或“no”),需要换用单选按钮。

// HTML
    <div>{{pick}}</div>
    <input type="checkbox" v-model="pick" true-value="yes" false-value="no">
    <!-- 当选中的时候,vm.pick === 'yes' -->
    <!-- 没有选中的时候,vm.pick === 'no' -->

// JS
  data(){
    return {
      pick:'no',
    }
  }
  • select
<select v-model="selected">
    <!-- 内联对象字面量 -->
  <option v-bind:value="{ number: 123 }">123</option>
</select>

// 当选中时
typeof vm.selected // => 'object'
vm.selected.number // => 123

在( 自定义 )组件上使用 v-model

HTML 原生的输入元素类型并不总能满足需求,而 Vue 组件系统允许创建具有完全自定义行为且可复用的输入组件。

这些输入组件可以和 v-model 一起使用!

使用场景:子组件想要使用父组件的值,又想去修改父组件的值


v-model 的修饰符

.lazy 

默认情况下, v-model 在每次 input 事件触发后,自动将输入框的值与数据进行同步。

如果希望在触发 change 事件的时候再进行数据的同步,可以使用 .lazy 修饰符:

// input事件和change事件的区别在于:
// input事件每当输入内容的时候,就会触发;而,change事件,是在失去焦点的时候触发。

// HTML
<input type="text" v-model.lazy="show" placeholder="请输入你想要搜索的内容">

// JS
data(){
    return{
        show:''
    }
}

.number 

在网页中,输入元素的值( 即使 type="number" )总是会返回字符串。

如果想自动把用户的输入值转换为数值类型,可以使用 .number 修饰符:

<input type="text" v-model.number="tel" type="number">

// 如果这个值无法被 parseFloat()解析,则会返回原始的值

.trim  如果要自动过滤用户输入的首尾空白字符,可以使用 .trim 修饰符:

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