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 相关文章推荐
关于js new Date() 出现NaN 的分析
Oct 23 Javascript
JS localStorage实现本地缓存的方法
Jun 22 Javascript
jQuery实现单击和鼠标感应事件
Feb 01 Javascript
JavaScript自定义等待wait函数实例分析
Mar 23 Javascript
jQuery实现的数值范围range2dslider选取插件特效多款代码分享
Aug 27 Javascript
JavaScript运行过程中的“预编译阶段”和“执行阶段”
Dec 16 Javascript
利用jquery实现瀑布流3种案例
Sep 18 Javascript
JavaScript实现通过select标签跳转网页的方法
Sep 29 Javascript
微信小程序 window_x64环境搭建
Sep 30 Javascript
解析Javascript单例模式概念与实例
Dec 05 Javascript
基于js原生和ajax的get和post方法以及jsonp的原生写法实例
Oct 16 Javascript
JS常用排序方法实例代码解析
Mar 03 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和ACCESS写聊天室(七)
2006/10/09 PHP
php 解析xml 的四种方法详细介绍
2016/10/26 PHP
thinkPHP5实现数据库添加内容的方法
2017/10/25 PHP
JavaScript 利用Cookie记录用户登录信息
2009/12/08 Javascript
javascript面向对象包装类Class封装类库剖析
2013/01/24 Javascript
js判断屏幕分辨率的代码
2013/07/16 Javascript
javascript中的self和this用法小结
2014/02/08 Javascript
JQuery做的一个简单的点灯游戏分享
2014/07/16 Javascript
JS小游戏之宇宙战机源码详解
2014/09/25 Javascript
jQuery给动态添加的元素绑定事件的方法
2015/03/09 Javascript
被遗忘的javascript的slice() 方法
2015/04/20 Javascript
原生js实现的贪吃蛇网页版游戏完整实例
2015/05/18 Javascript
angularjs学习笔记之三大模块(modal,controller,view)
2015/09/26 Javascript
JS实现部分HTML固定页面顶部随屏滚动效果
2015/12/24 Javascript
关于JSON.parse(),JSON.stringify(),jQuery.parseJSON()的用法
2016/06/30 Javascript
NodeJS和BootStrap分页效果的实现代码
2016/11/07 NodeJs
ES6中箭头函数的定义与调用方式详解
2017/06/02 Javascript
vue better scroll 无法滚动的解决方法
2018/06/07 Javascript
vue-cli3+ts+webpack实现多入口多出口功能
2019/05/30 Javascript
pm2启动ssr失败的解决方法
2019/06/29 Javascript
微信小程序实现多图上传
2020/06/19 Javascript
如何在postman中添加cookie信息步骤解析
2020/06/30 Javascript
vue 判断页面是首次进入还是再次刷新的实例
2020/11/05 Javascript
[04:03]DOTA2肉山黑名单梦之声 风暴之灵中文配音鉴赏
2013/07/03 DOTA
[33:23]VG vs Pain 2018国际邀请赛小组赛BO2 第二场 8.18
2018/08/19 DOTA
Python获取当前函数名称方法实例分享
2018/01/18 Python
Python针对给定字符串求解所有子序列是否为回文序列的方法
2018/04/21 Python
Python使用add_subplot与subplot画子图操作示例
2018/06/01 Python
pytorch多进程加速及代码优化方法
2019/08/19 Python
Python实现一个简单的毕业生信息管理系统的示例代码
2020/06/08 Python
Python第三方包PrettyTable安装及用法解析
2020/07/08 Python
利用Python实现学生信息管理系统的完整实例
2020/12/30 Python
2014年医学生毕业自我鉴定
2014/03/26 职场文书
医疗纠纷调解协议书
2015/08/06 职场文书
三年级作文之趣事作文
2019/11/04 职场文书
python如何获取网络数据
2021/04/11 Python