v-model虽然很像使用了双向数据绑定的 Angular 的 ng-model,但是 Vue 是单项数据流,v-model 只是语法糖而已:

<input v-model="sth" />
<input v-bind:value="sth" v-on:input="sth = $event.target.value" />

第一行的代码其实只是第二行的语法糖。然后第二行代码还能简写成这样:

<input :value="sth" @input="sth = $event.target.value" />

要理解这行代码,首先你要知道 input 元素本身有个 oninput 事件,这是 HTML5 新增加的,类似 onchange ,每当输入框内容发生变化,就会触发 oninput ,把最新的value传递给 sth

我们仔细观察语法糖和原始语法那两行代码,可以得出一个结论:

在给 <input /> 元素添加 v-model 属性时,默认会把 value 作为元素的属性,然后把 'input' 事件作为实时传递 value 的触发事件

v-model 用在组件上时

v-model 不仅仅能在 input上用,在组件上也能使用,下面是一个和 Vue 官网教程类似的例子(在看这个例子时我们要考虑两个问题):

父组件的 price 的初始值是 100,更改子组件的值能实时更新父组件的 price

<div id="demo">
<currency-input v-model="price"></currentcy-input>
<span>{{price}}</span>
</div>
<script src="https://cdn.bootcss.com/vue/2.3.0/vue.js"></script>
<script>
Vue.component('currency-input', {
template: `
<span>
<input
ref="input"
:value="value"
<!--为什么这里把 'input' 作为触发事件的事件名?`input` 在哪定义的?-->
@input="$emit('input', $event.target.value)"
>
</span>
`,
props: ['value'],// 为什么这里要用 value 属性,value在哪里定义的?貌似没找到啊?
}) var demo = new Vue({
el: '#demo',
data: {
price: 100,
}
})
</script>

如果你知道这两个问题的答案,那么恭喜你真正掌握了 v-model,如果你没明白,那么可以看下这段代码:

<currency-input v-model="price"></currentcy-input>
<!--上行代码是下行的语法糖
<currency-input :value="price" @input="price = arguments[0]"></currency-input>
-->

现在你知道 value 和 input 从哪来的了吧。与上面总结的类似:

给组件添加 v-model 属性时,默认会把 value 作为组件的属性,然后把 'input' 值作为给组件绑定事件时的事件名

v-model 的缺点和解决办法

在创建类似复选框或者单选框的常见组件时,v-model就不好用了。

<input type="checkbox" v-model="sth" />

v-model 给我们提供好了 value 属性和 oninput 事件,但是,我们需要的不是 value 属性,而是 checked 属性,并且当你点击这个单选框的时候不会触发 oninput 事件,它只会触发 onchange 事件。这就尴尬了。

因为 v-model 只是用到了 input 元素上,所以这种情况好解决:

<input type="checkbox" :checked="status" @change="status = $event.target.checked" />
<my-checkbox v-model="foo"></my-checkbox>

Vue.component('my-checkbox', {
tempalte: `<input
type="checkbox"
<!--这里就不用 input 了,而是 balabala-->
@change="$emit('balabala', $event.target.checked)"
:checked="checked"
/>`
props: ['checked'], //这里就不用 value 了,而是 checked
model: {
prop: 'checked',
event: 'balabala'
},
})

最新文章

  1. 2_MVC+EF+Autofac(dbfirst)轻型项目框架_用户权限验证
  2. 解密jQuery事件核心 - 绑定设计(一)
  3. 封装自己的Common.js工具库
  4. 一种更清晰的Android架构(转)
  5. 合工大OJ 1330 种树
  6. ruby on rails gem install pg时无法安装
  7. leetcode-Consecutive numbers
  8. angular 数据加载动画 longding
  9. C语言中头文件和cpp文件解析
  10. c,assert 宏的实现
  11. mysql按ID排序(转)
  12. hive load from hdfs出错
  13. CSS深入理解学习笔记之overflow
  14. C#基础第二天
  15. TIDB 备忘
  16. [UE4]Static Mesh的碰撞体
  17. html2canvas html截图插件
  18. HDU2873 Bomb Game(二维SG函数)
  19. golang 本地构建包
  20. tabs高度自适应方法

热门文章

  1. python读取数据写入excel
  2. 最大公约数and最小公倍数(Java版)
  3. 手写RPC
  4. 【LeetCode】面试题62. 圆圈中最后剩下的数字
  5. scrapy 使用crawlspider rule不起作用的解决方案
  6. 一、MinIO的基本概念
  7. Java_classpath
  8. SpringCloud升级之路2020.0.x版-12.UnderTow 简介与内部原理
  9. MyBatis学习05(多对一和一对多)
  10. MySQL-11-存储引擎