用过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双向绑定支持的更多相关文章

  1. react第十一单元(受控组件和非受控组件-实现类似于vue双向绑定的功能)

    第十一单元(受控组件和非受控组件-实现类似于vue双向绑定的功能) #课程目标 理解因为react的单向数据流 理解表单组件会因为react数据流变的不好维护 理解受控组件与非受控组件的实质区别 理解 ...

  2. vue 实现父组件和子组件之间的数据双向绑定

    前言:vue 实现父组件给子组件传值,然后子组件可以修改回父组件的值.vue 的 prop 默认是单向数据绑定,但是偶尔需要双向绑定,这时就需要知道如何才能让子组件的数据修改时影响到父组件的数据.转载 ...

  3. (复习)父子组件传值使用v-modal双向绑定,报错Avoid mutating a prop directly解决方案

    报错:Avoid mutating a prop directly since the value will be overwritten whenever the parent component. ...

  4. vue model双向绑定

    view <div id='demo' class="container"> <input type="text" v-model='name ...

  5. 面试问题:Vuejs如何实现双向绑定

    最近出去面试,栽在这个问题上,提到vuejs,面试官一般会让你说vuejs的特点,一般就要回答virtual dom tree, dom tree diff, 以及数据双向绑定,然后面试官会追问你,v ...

  6. 如何在Vue2中实现组件props双向绑定

    Vue学习笔记-3 前言 Vue 2.x相比较Vue 1.x而言,升级变化除了实现了Virtual-Dom以外,给使用者最大不适就是移除的组件的props的双向绑定功能. 以往在Vue1.x中利用pr ...

  7. angularjs1.x版本,父子组件之间的双向绑定

    今天遇到了一个angularjs的坑, ng-repeat和ng-if会改变他所包含的html中绑定变量的作用域. angularjs自定义指令,可以定义四种变量,通过 =,@,&双向绑定,单 ...

  8. Vuejs——(8)Vuejs组件的定义

    版权声明:出处http://blog.csdn.net/qq20004604   目录(?)[+]   本篇资料来于官方文档: http://cn.vuejs.org/guide/components ...

  9. 深入理解 Vuejs 组件

    本文主要归纳在 Vuejs 学习过程中对于 Vuejs 组件的各个相关要点.由于本人水平有限,如文中出现错误请多多包涵并指正,感谢.如果需要看更清晰的代码高亮,请跳转至我的个人站点的 深入理解 Vue ...

随机推荐

  1. 其他综合-CentOS7 安装 Jumpserver 跳板机

    CentOS7 安装 Jumpserver 跳板机 1.实验描述 搭建 jumpserver 平台,实现有效的运维安全审计.完美做到事先防范,事中控制和事后溯源 2.实验环境 物理机系统:Window ...

  2. AssetBundleMaster_ReadMe_CN

    在开始使用之前, 建议先导入到一个空的工程里, 通过ReadMe的一步步引导使你对整个框架以及文件结构进行熟悉, 之后再考虑导入到现有工程中使用, 完整看完教程大概需要2个小时左右. 先看看文件夹结构 ...

  3. 无法解析的外部符号 "void __cdecl cv::imshow

    解决方法: 把编译环境放到其他没有报错的项目上,编译通过.

  4. JS高阶---回调函数

    1.什么函数是回调函数? 此时两者的执行并没有先后顺序 两个都是回调函数 满足三个特点就是回调 .定义了函数 .没有主动调用 .最后执行了 2.常见的回调函数有哪些? .DOM事件回调函数 .定时器回 ...

  5. day31_8.12并发编程二线程

    一.进程间的通信 在进程中,可以通过Queue队列进行通信,队列有两个特点: 1.先进先出.(先来的数据先被取出) 2.管道式存取.(数据取出一次后就不会在有了) 在python中有以下方法来操作数据 ...

  6. 【转】前后端分离的项目如何部署发布到Linux

    前后端分离的项目如何部署发布到Linux 前期准备 1.服务器的基本配置信息2.本机远程连接服务器的工具(xshell.xftp或者mobaXterm等等,看你自己喜欢) 第一步:部署环境 1.安装j ...

  7. static inline和inline的区别——stm32实测

    参考:http://armbbs.cn/forum.php?mod=viewthread&tid=95190&extra=page%3D1 对于内联函数,不能像普通函数那样,直接在.h ...

  8. minio select api 试用

    对于minio 我们可以使用基于sql 的对象内容查询,特别适合进行特定文件内容的获取,强大方便. 以下是一个简单的试用 环境准备 集成了prometheus docker-compose 文件   ...

  9. [LeetCode] 915. Partition Array into Disjoint Intervals 分割数组为不相交的区间

    Given an array A, partition it into two (contiguous) subarrays left and right so that: Every element ...

  10. [LeetCode] 891. Sum of Subsequence Widths 子序列宽度之和

    Given an array of integers A, consider all non-empty subsequences of A. For any sequence S, let the  ...