Vue 进阶教程之v-model详解


Posted in Javascript onMay 06, 2017

Vue 官网教程上关于 v-model 的讲解不是十分的详细,写这篇文章的目的就是详细的剖析一下, 并介绍 Vue 2.2  v-model改进的地方,然后穿插的再说点 Vue 的小知识。

在 Vue 中,有许多方法和 Angular 相似,这主要是因为 Angular 是 Vue 早期开发的灵感来源。然而,Augular 中存在许多问题,在 Vue 中已经得到解决。

v-model 用在 input 元素上时

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。

如果你不知道 $event 是从哪来的,那你需要点击它再复习一下文档。

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

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

v-model 用在组件上时

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

Vue 进阶教程之v-model详解

父组件的 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" />

当 v-model 用到组件上时:↓

<my-checkbox v-model="foo"></my-checkbox>

Vue.component('my-checkbox', {
 tempalte: `<input 
        type="checkbox"
        @change="$emit('input', $event.target.checked)"
        :checked="value"
       />`
 props: ['value'],
})

在 Vue 2.2 版本,你可以在定义组件时通过 mode l选项的方式来定制 prop/event:↓

<my-checkbox v-model="foo"></my-checkbox>

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

看到这里我相信你肯定理解了 Vue 的 v-model,文中如有错误,欢迎在评论中指出谢谢。希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
DIY jquery plugin - tabs标签切换实现代码
Dec 11 Javascript
JS实现简单的Canvas画图实例
Jul 04 Javascript
IE6下拉框图层问题探讨及解决
Jan 03 Javascript
AngularJS实现分页显示数据库信息
Jul 01 Javascript
JavaScript中数组的22种方法必学(推荐)
Jul 20 Javascript
详解JavaScript的内置对象
Dec 07 Javascript
div实现自适应高度的textarea实现angular双向绑定
Jan 08 Javascript
jQuery实现模糊搜索功能的方法分析
Jun 29 jQuery
jquery获取select选中值的文本,并赋值给另一个输入框的方法
Aug 21 jQuery
微信小程序如何实现点击图片放大功能
Jan 21 Javascript
javascript canvas封装动态时钟
Sep 30 Javascript
vue+swiper实现左右滑动的测试题功能
Oct 30 Javascript
jQuery动态追加页面数据以及事件委托详解
May 06 #jQuery
AngularJS封装$http.post()实例详解
May 06 #Javascript
JavaScript瀑布流布局实现代码
May 06 #Javascript
jquery点赞功能实现代码 点个赞吧!
May 29 #jQuery
jQuery extend()详解及简单实例
May 06 #jQuery
jquery仿微信聊天界面
May 06 #jQuery
Javascript实现页面滚动时导航智能定位
May 06 #Javascript
You might like
PHP中CURL方法curl_setopt()函数的参数分享
2013/01/19 PHP
php中stdClass的用法分析
2015/02/27 PHP
PHP实现微信模拟登陆并给用户发送消息的方法【文字,图片,图文】
2017/06/29 PHP
php实现微信分享朋友链接功能
2019/02/18 PHP
关于Anemometer图形化显示MySQL慢日志的工具搭建及使用的详细介绍
2020/07/13 PHP
Jquery替换已存在于element上的event的方法
2010/03/09 Javascript
收集的一些Array及String原型对象的扩展实现代码
2010/12/05 Javascript
Script的加载方法小结
2011/01/12 Javascript
js 第二代身份证号码的验证机制代码
2011/05/12 Javascript
用jQuery中的ajax分页实现代码
2011/09/20 Javascript
获取中文字符串的实际长度代码
2014/06/05 Javascript
jQuery和AngularJS的区别浅析
2015/01/29 Javascript
详细解读AngularJS中的表单验证编程
2015/06/19 Javascript
只需五句话搞定JavaScript作用域(经典)
2016/07/26 Javascript
jQuery实现表格元素动态创建功能
2017/01/09 Javascript
微信小程序 点击控件后选中其它反选实例详解
2017/02/21 Javascript
vue打包的时候自动将px转成rem的操作方法
2018/06/20 Javascript
js根据需要计算数组中重复出现某个元素的个数
2019/01/18 Javascript
layui原生表单验证的实例
2019/09/09 Javascript
Vue ElementUI实现:限制输入框只能输入正整数的问题
2020/07/31 Javascript
[01:02:46]VGJ.S vs NB 2018国际邀请赛小组赛BO2 第二场 8.18
2018/08/19 DOTA
用Python编写一个每天都在系统下新建一个文件夹的脚本
2015/05/04 Python
python中for用来遍历range函数的方法
2018/06/08 Python
Python嵌套列表转一维的方法(压平嵌套列表)
2018/07/03 Python
flask入门之表单的实现
2018/07/18 Python
python实现斗地主分牌洗牌
2020/06/22 Python
简单掌握CSS3将文字描边及填充文字颜色的方法
2016/03/07 HTML / CSS
英国最大的汽车配件在线商店:Euro Car Parts
2019/09/30 全球购物
关爱留守儿童倡议书
2014/04/15 职场文书
爱心捐款感谢信
2015/01/20 职场文书
酒店人事主管岗位职责
2015/04/11 职场文书
2015高中教师个人工作总结
2015/07/21 职场文书
法院执行局工作总结
2015/08/11 职场文书
500字作文之关于爸爸
2019/11/14 职场文书
Java常用工具类汇总 附示例代码
2021/06/26 Java/Android
gateway与spring-boot-starter-web冲突问题的解决
2021/07/16 Java/Android