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'
},
})

vue 之 v-model的更多相关文章

  1. Vue中的model

    v-model语法糖: model: 默认情况下,一个组件上的 v-model 会把 value 用作 prop 且把 input 用作 event, 但是一些输入类型比如单选框和复选框按钮可能想使用 ...

  2. 对于vue绑定的model值里边get和set的小动作

    先看下例子: template里边内容: <el-form-item label="导航条类型"> <el-radio-group v-model="n ...

  3. 4.vue class 绑定- model基础应用

        //代码可以复制自行体验   <template>     <div id="app" @click.stop="test('你点击了我big- ...

  4. 第六十二篇:Vue的双向绑定与按键修饰符

    好家伙,依旧是vue的基础 1.按键修饰符 假设我们在一个<input>框中输入了12345,我们希望按一下"Esc" 然后删除所有前面输入的内容,这时候,我们会用到按 ...

  5. vue中动态循环model

    vue动态循环model与angular有所不同,angular直接定义一个数组,然后传入循环列表的index即可. 而vue不仅需要定义一个数组,还需要通过接口读出循环的数组长度,然后在create ...

  6. vue 自定义封装组件 使用 model 选项

    自定义组件的 v-model 一个组件上的 v-model 默认会利用名为 value 的 prop 和名为 input 的事件,但是像单选框.复选框等类型的输入控件可能会将 value 特性用于不同 ...

  7. vue.js初级入门之最基础的双向绑定操作

    首先在页面引入vue.js以及其他需要用到的或者可能要用到的插件(这里我多引用了bootstrap和jquery) 引用的时候需要注意文件的路径,准备工作这样基本就完成了,下面正式开始入门. vue. ...

  8. 如何用vue实现树形菜单?

    在公司培训了2周,布置的作业是从树形,grid分页以及echarts中选一个.由于都不是很熟,就挑了第一个.本来想在网上找找参考,然后模仿着做一个,但是网上的代码多少参差不齐,写到一半没了,所以只要自 ...

  9. vue组件详解(三)——组件通信

    组件之间通信可以用下图表示: 组件关系可分为父子组件通信.兄弟组件通信.跨级组件通信. 一.自定义事件 当子组件需要向父组件传递数据时,就要用到自定义事件. 子组件用$emit ()来触发事件,父组件 ...

  10. 基于Django rest framework 和Vue实现简单的在线教育平台

      一.基于api前端显示课程详细信息 1.调整Course.vue模块 ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 2 ...

随机推荐

  1. 流暢的pyhton4---數據庫備份

    一.linux數據庫備份腳本 1.数据库备份,命令如下: ./pg_dump -h localhost -p 5432 -U postgres -W -F c -b -v -f "/opt/ ...

  2. odoo里面条件写法

    attrs="{'invisible': ['|', ('probability', '>', 0), ('active', '=', True)]}"/>. 写法gt ...

  3. Git,Linux,Ubuntu,Tmux的常用命令

    常用的连接 Git命令 廖雪峰的Git教程 Git常用命令 ubuntu16.04之GitHub入门教程 Linux相关 tmux命令 Ubuntu常用命令速查手册 Linux 命令大全 其它工具 M ...

  4. Android 模块打包生成aar远程坐标(sdk)

    Android 模块打包生成aar远程坐标 打包成AAR到本地仓库 在模块的gradle文件中加入apply plugin: 'maven'  *repository(url:"file:/ ...

  5. Genymotion模拟器安装ARM架构编译应用失败解决方案

    我们在安装一些应用到Genymotion模拟器会提示:adb: failed to install xx.apk: Failure [INSTALL_FAILED_NO_MATCHING_ABIS: ...

  6. Input 只能输入正数以及2位小数点

    <input onkeyup="this.value= this.value.match(/\d+(\.\d{0,2})?/) ? this.value.match(/\d+(\.\d ...

  7. cas5.3.1 从搭建到连接mysql(简而优美)

    前言: cas是单点登录服务框架,为单点登录业务提供了便捷服务,它分为client,server端,client端要聚合到我们自己的项目. server端要单独构建运行,本篇文章主要讲解一下cas5. ...

  8. 1009 Product of Polynomials (25分) 晚上脑子就是容易僵住

    #include<iostream> using namespace std; struct { int a; double b; }poly[1001]; double a[2001]; ...

  9. python爬虫:了解JS加密爬取网易云音乐

    python爬虫:了解JS加密爬取网易云音乐 前言 大家好,我是"持之以恒_liu",之所以起这个名字,就是希望我自己无论做什么事,只要一开始选择了,那么就要坚持到底,不管结果如何 ...

  10. Docker小白到实战之容器数据卷,整理的明明白白

    前言 上一篇把常用命令演示了一遍,其中也提到容器的隔离性,默认情况下,容器内应用产生的数据都是由容器本身独有,如果容器被删除,对应的数据文件就会跟着消失.从隔离性的角度来看,数据就应该和容器共存亡:但 ...