给定制的vuejs组件添加v-model双向绑定支持
用过vuejs的前端工程师,对于v-model一定印象深刻。它向类似textarea,input等原生html原生添加双向数据绑定的能力非常方便。但是对于你的定制vue组件并不是能够直接应用v-model的,我们需要做一些额外的工作,但是这个额外工作是非常简单的。
为了理解如何给你的组件提供v-momeiydel支持,你应该深入地了解v-model本身底层是如何工作地。v-model初看起来就像是一个魔术,但是真的没有那么神秘。
v-model="syncedProp"
等价于以下代码
:value="syncedProp" @input="syncedProp=$arguments[0] 或者
:value="syncedProp" @input="syncedProp=$event.target.value
理解了以上地两点,那么如果需要支持v-model,你自己的组件需要做的就是:
1. 接收一个:value的property
2. 当用户变更value值的时候发送一个@input事件
基础实现:
我们假设我们有一个date picker的组件,该组件接收year,month的value:{month:1,year:2019},我们希望该组件有两个输入Inputs,一个用于month,一个用于year,并且通过v-model来更新绑定的对象.这里是实现的例子代码:
<template>
<div class="date-picker">
Month: <input type="number" ref="monthPicker" :value="value.month" @input="updateDate()"/>
Year: <input type="number" ref="yearPicker" :value="value.year" @input="updateDate()"/>
</div>
</template> <script>
export default {
props: ['value'], methods: {
updateDate() {
this.$emit('input', {
month: +this.$refs.monthPicker.value,
year: +this.$refs.yearPicker.value
})
}
}
};
</script>
有了以上的实现代码后,我们就可以像下面的代码来使用它:
<template>
<div class="wrapper">
<date-picker v-model="date"></date-picker>
<p>
Month: {{date.month}}
Year: {{date.year}}
</p>
</div>
</template> <script>
import DatePicker from './DatePicker.vue'; export default {
components: {
DatePicker
}, data() {
return {
date: {
month: 1,
year: 2017
}
}
}
})
</script>
总结以上范例代码,我们可以看到就做了两件事:
1. 接受一个value这个prop,并通过该value prop传入的值在本组件中使用
2. 当需要通知外部数据已经变化需要更新外部的绑定数据时,只需要emit一个input事件即可!
高级一点的例子
在上面基础版本基础上,我们把事情搞得稍微复杂一点,比如,我们传入的日期格式不是object形式,而时字符串形式mm/yyyy的格式,这时需要使用的化,必须要做进一步处理,同样地,当用户主动修改了数据修正外部地数据时,也需要再组合成一个字符串emit出去!
<template>
<div class="date-picker">
Month: <input type="number" ref="monthPicker" :value="splitDate.month" @input="updateDate()"/>
Year: <input type="number" ref="yearPicker" :value="splitDate.year" @input="updateDate()"/>
</div>
</template> <script>
export default {
props: ['value'], computed: {
splitDate() {
const splitValueString = this.value.split('/'); return {
month: splitValueString[0],
year: splitValueString[1]
}
}
}, methods: {
updateDate() {
const monthValue = this.$refs.monthPicker.value;
const yearValue = this.$refs.yearPicker.value;
this.$emit('input', `${monthValue}/${yearValue}`);
}
}
};
</script>
定制v-model所使用的prop和event
如上面所说,v-model匹配的就是value属性以及input的事件上报,但是我们也可以修改这个默认的行为。
其办法就是通过在我们的定制组件中,声明一个model对象,该model对象包含两个字段,一个prop,一个event分别用于对应的value和input事件
比如下面的组件代码:
export default {
prop: ['cprop'],
model: {
prop: 'cprop',
event: 'cevent'
}
methods: {
handleInput (value) {
this.$emit('cevent', value)
}
}
}
如果我们在html中像下面来使用:
<basic-input v-model="email" />
<!-- 等价于以下代码 -->
<basic-input :cprop="email" @cevent="e => email = e.target.value" />
给定制的vuejs组件添加v-model双向绑定支持的更多相关文章
- react第十一单元(受控组件和非受控组件-实现类似于vue双向绑定的功能)
第十一单元(受控组件和非受控组件-实现类似于vue双向绑定的功能) #课程目标 理解因为react的单向数据流 理解表单组件会因为react数据流变的不好维护 理解受控组件与非受控组件的实质区别 理解 ...
- vue 实现父组件和子组件之间的数据双向绑定
前言:vue 实现父组件给子组件传值,然后子组件可以修改回父组件的值.vue 的 prop 默认是单向数据绑定,但是偶尔需要双向绑定,这时就需要知道如何才能让子组件的数据修改时影响到父组件的数据.转载 ...
- (复习)父子组件传值使用v-modal双向绑定,报错Avoid mutating a prop directly解决方案
报错:Avoid mutating a prop directly since the value will be overwritten whenever the parent component. ...
- vue model双向绑定
view <div id='demo' class="container"> <input type="text" v-model='name ...
- 面试问题:Vuejs如何实现双向绑定
最近出去面试,栽在这个问题上,提到vuejs,面试官一般会让你说vuejs的特点,一般就要回答virtual dom tree, dom tree diff, 以及数据双向绑定,然后面试官会追问你,v ...
- 如何在Vue2中实现组件props双向绑定
Vue学习笔记-3 前言 Vue 2.x相比较Vue 1.x而言,升级变化除了实现了Virtual-Dom以外,给使用者最大不适就是移除的组件的props的双向绑定功能. 以往在Vue1.x中利用pr ...
- angularjs1.x版本,父子组件之间的双向绑定
今天遇到了一个angularjs的坑, ng-repeat和ng-if会改变他所包含的html中绑定变量的作用域. angularjs自定义指令,可以定义四种变量,通过 =,@,&双向绑定,单 ...
- Vuejs——(8)Vuejs组件的定义
版权声明:出处http://blog.csdn.net/qq20004604 目录(?)[+] 本篇资料来于官方文档: http://cn.vuejs.org/guide/components ...
- 深入理解 Vuejs 组件
本文主要归纳在 Vuejs 学习过程中对于 Vuejs 组件的各个相关要点.由于本人水平有限,如文中出现错误请多多包涵并指正,感谢.如果需要看更清晰的代码高亮,请跳转至我的个人站点的 深入理解 Vue ...
随机推荐
- Windows 下 pycharm 创建Django 项目【用虚拟环境的解释器】
1. 背景 我在 Windows 下的 pycharm 直接创建 全新 Django 项目 会 pip 和其他报错 ,暂时解决不了,另外后续的多个项目只需要一套python 环境, 所以可以 ...
- shell 大小关系 -eq -ne
-eq:等于-ne:不等于-le:小于等于-ge:大于等于-lt:小于-gt:大于
- jQuery的DataTables中的TableTools的基本使用
DataTables的TableTools插件提供复制,导出excel.pdf,打印等功能. DataTables官网:http://datatables.net TableTools示例:http: ...
- luoguP3327 [SDOI2015]约数个数和
题意 首先有个结论: \(d(i,j)=\sum\limits_{x|i}\sum\limits_{y|j}[gcd(x,y)=1]\) 证明: 假设\(i=p_1^{a_1}*p_2^{a_2}*. ...
- idea中怎么忽略(ignore)掉 .idea等文件
idea需要下载一个专门的plugins 来ignore .idea *.iml等文件 可以在https://plugins.jetbrains.com/idea/plugin/7495–ignore ...
- 微信小程序特性总结
一. 小程序不是运行在浏览器中, 所以没有BOM和DOM对象 即console.log(window)和console.log(document)是获取不到任何内容的 二. 小程序特有的额外js成员( ...
- Linux性能优化实战学习笔记:第四十六讲
一.上节回顾 不知不觉,我们已经学完了整个专栏的四大基础模块,即 CPU.内存.文件系统和磁盘 I/O.以及网络的性能分析和优化.相信你已经掌握了这些基础模块的基本分析.定位思路,并熟悉了相关的优化方 ...
- 2020年数据库概念与MySQL的安装与配置-从零基础入门MySQL-mysql8版本
作者 | Jeskson 来源 | 达达前端小酒馆 从零基础入门MySQL数据库基础课 数据的概念,简介,安装与配置,Windows平台下MySQL的安装与配置. 数据库的概念:数据库是一个用来存放数 ...
- [LeetCode] 51. N-Queens N皇后问题
The n-queens puzzle is the problem of placing n queens on an n×n chessboard such that no two queens ...
- 面试:Semaphore(信号量)的成长之路
2019最寒冷,面试跳槽不能等 马上就3月份了,所谓的金三银四招聘季.2019年也许是互联网最冷清的一年,很多知名的大型互联网公司都裁员过冬.当然也有一些公司还在持续招人的,比如阿里就宣称不裁员,反而 ...