组件通信专题
一、vue2中常用的6中组件通信方式
1. props
适用于的场景:父子组件通信
注意事项:
如果父组件给子组件传递数据(函数):本质其实是子组件给父组件传递数据。
如果父组件给子组件传递数据(非函数):本质就是父组件给子组件传递数据。
书写方式:3种
['todos'],{type:Array},{type:Array,default:[]}
小提示:路由的props 书写形式:布尔值,对象、函数形式
2. 自定义事件
适用于场景:子组件给父组件传递数据
$on
与$emit
3. 全局事件总线$bus
适用于场景:万能
Vue.prototype.$bus = this
4. pubsub-js
在React框架中使用比较多。(发布与订阅)
适用于场景:万能
5. Vuex
使用于场景:万能
6. 插槽
适用于场景:父子组件通信----(一般结构)
默认插槽
具名插槽
作用域插槽(重写饿了么的表格组件常用)
二、事件分类
在学习新的组件通信方式前,我们先来了解一下事件的种类,顺便回顾一下已经学过的组件通信方式。
事件分为两类
- 原生DOM事件:click、双击、鼠标系列等等。
- 自定义事件。
需要注意的是:
原生DOM节点(如果div,button等)绑定click事件默认是系统事件,而非原生DOM节点(组件标签)绑定click事件默认是自定义事件,要想把click自定义事件变成原生DOM事件需要在事件绑定后面跟上.native
,如@click.native=""
。
如若没有加.native
则需要以自定义事件的方式来触发事件,即在子组件中使用$emit
触发函数。
下面我们通过代码来帮助理解
三、深入v-model
1. v-model的原理
原生DOM当中有oninput
事件,它经常结合表单元素一起使用,oninput
事件是一个键盘输入事件,当表单元素文本内容发生变化的时候就会触发一次回调。
在vue2中,通过value
(单向绑定,全称是v-bind:value
)和input
事件实现v-model
的功能。如下图:
其实这里就是单向绑定msg的值,触发onInput
事件,近似于调用了一个匿名函数修改了msg,从而实现双向绑定。
2. v-model实现父子组件数据同步
v-model
它是Vue框架中指令,它主要结合表单元素一起使用(文本框、复选、单选等等),它的主要作用是收集表单数据。
通过下图方式可以实现父子组件数据同步。
值的注意的是:
-
父组件中调用子组件所使用的
:value
是props组件通信,而不是原生DOM的单向数据绑定,所调用的@input
事件也并非原生DOM事件,而是自定义事件。 -
子组件中
input
输入框所使用的:value
是原生DOM的单向数据绑定,所调用的@input
事件是原生DOM事件。 -
父组件中
@input
绑定的事件中的$event
用于接收子组件中通过$emit
传递来的数据扩展:
$event
的两个应用场景- 获取原生DOM事件的事件对象。
- 事件注册所传的参数(子组件向父组件传值)。
总结:
v-model
实现原理:value
与input
事件实现的。
另外可以通过v-model
实现父子组件数据同步。
四、属性修饰符sync
实现父子组件通信
属性修饰符sync
也可以实现组件数据同步。如下图
结果演示
:money.sync
代表父组件给字符串传递propsmoney
,给当前子组件绑定一个自定义事件update:money
。
五、组件属性$attrs
和$listeners
实现父子组件通信
$attrs
属于组件的一个属性,可以获取到父组件传递过来的props数据。
对于子组件而言,父组件给的数据可以利用props接受,但是需要注意的是,子组件通过props接受到的属性,在$attrs
当中是获取不到的。
$listeners
也是组件的一个属性,它可以获取到父组件给子组件传递的自定义事件。
那么如何在子组件中使用$attrs
和$listeners
呢?
v-bind="$attrs"
v-on="$listeners"
注意:使用这两个属性v-bind
不能用:
代替,v-on
不能用@
代替。
下面我们通过实例来加深理解
效果演示
六、组件属性$children
和$parent
实现父子组件通信
ref
可以获取到某一个组件,子组件【最常用】
组件实例自身拥有一个属性$children
,可以获取到当前组件当中的全部子组件,
$parent
可以获取到当前子组件的父组件,进而可以操作父组件的数据和方法。
效果演示
七、插槽实现父子组件通信
待补。