vue组件中的通讯方式

前言

在vue中,组件间的通讯方式尤其重要。首先,咱们来讲如下 组件间的关系有哪些呢?父子组件,兄弟组件以及隔代组件。关于父子组件中通讯方式,最经常使用的就是props,$emit,兄弟组件间的通讯方式有eventBus,vuex等方式。然而 ,忽然发现还有好几种组件通讯的方式未被开启。因此,在这里,总结一下vue中的组件通讯方式有哪些,每种方式 又都有什么奥妙的地方。vue

1.props和$emit

其实,这种方式是咱们在vue中常用的,对于它的用法就在这里不一一细说了。只说一下关于它的使用的注意事项。
首先,说一下,在父子组件间的通讯,数据的流向是单向数据流的。
全部的prop都使用的其父子prop之间造成一个单向下行绑定:父级prop的更新会向下流动到子组件中,可是反过来则不行。这样会防止从子组件意外改变父级组件的状态,从而致使你的应用的数据流难以理解。
额外的,每次父级组件发生更新时,子组件中全部的prop都将会刷新为最新的值。这意味着你不该该在一个子组件内部改变你prop。若是你这样子作了,vue会在浏览器的控制台中发出警告。 ---vue官方文档。
昨天,看一位同事的代码,忽然发现了一个很吊的操做,不是在组件中对父组件中传过来的props(好比:字符串,数值类型)直接修改会提示错误信息吗?可是对于父组件中传过来的props(对象),修改其中的某一个属性是不会报错的。因此,利用这一点,在子组件中传入对象的类型,而后修改其中某一个属性。其实,这种操做虽然没有报错,可是其实,在改变子组件中的同时,也改变了父组件中的数据。这种方案仍是不可取的。
子组件:在子组件中更改父组件的数据,vuex

clipboard.png
父组件:在父组件监听一下 ,在子组件更改父组件中的数据的时候,父组件中的这个数据是否发生变化。
clipboard.png
那有没有什么解决方案呢?数组

1.在子组件中定义一个数据,去接收传过来的数据.

clipboard.png

2.若是传入到子组件的数据须要转换的话,可使用计算属性来实现。
3.v-model的使用方式
在父组件中,子组件绑定v-model:
![clipboard.png](/img/bVbw4QI)
在子组件中,除了要在props中声明以外,还须要再model中进行声明:
![clipboard.png](/img/bVbw4QR)

2.vuex

咱们在学习vue的同时,也基本会学习使用vuex,vuex是一个数据状态管理器,而放在store中的数据,是全局状态的,正是由于这个特性,咱们可使用vuex进行兄弟组件间的传值。关于vuex的使用,你们能够看官网学习一下:https://vuex.vuejs.org/zh/guide/浏览器

3.$parent,$children

$parent:指定已建立的实例之父的实例,在二者之间创建了父子关系。子实例能够经过this.$parent访问实例,子实例被推入父实例的$children中。
例如:在子组件中打印this.$parent的结果是一个对象,里面是父组件的信息:dom

clipboard.png
$children:当前实例的子组件。例如:在父组件中打印this.$children能够获取到一个数组,这个数组里面包含其全部的子组件。ide

clipboard.png

4.$listeners $attrs:

适用于隔代组件,且中间组件只是为了数据的传递。例如:A组件包含B组件,B组件包含C组件。须要将A组件中的message这个数据传到C组件中。常见的写法,就是咱们先将A组件中的message数据传递到B组件中,而后再由B组件传递到C组件。而后,在这里,介绍一种新的写法:#attrs,$listenters.
$attrs包含了父做用域中不做为prop被识别(且获取)的特性绑定(class和style除外)。当一个组件没有声明任何prop时,这里会包含全部父做用域的绑定(class和style除外),而且能够经过v-bind="$attrs"传入内部组件--在建立高级别的组件时很是有用。
emmm...上面这句话,读着挺绕口的,就是简单来讲,将父组件中传入的数据到子组件,而后子组件中没有使用prop接收的数据都存放在$attrs中,若是想把$attrs中的数据传到内部子组件,就能够直接在子组件上v-bind="$attrs"上传入到内部子组件。函数

A组件(传入text1,text2到B组件):学习

clipboard.png

B组件(只接受了text1,没有接收text2,使用$attrs将text2传到C组件):ui

clipboard.png

C组件(接收text2):this

clipboard.png

结果展现:

clipboard.png

上面这个简单的例子,就详情的介绍了一下$attrs的使用,这种方式的使用对于隔代组件通讯的使用,自我感受是很方便的。

$listeners:包含了父做用域中的(不含.native修饰器)v-on事件监听器,它能够经过v-on=$listeners 传入内部组件--在建立更高层次的组件时sh很是有用的。
这个属性就是和$attrs时相似的,只不过是自定义事件从子组件传到父组件的使用。

clipboard.png

5.Provide inject的使用(主要为高阶插件/组件库提供用例。)

provide选项是一个对象或者返回一个对象的函数。该对象包含可注入其子孙的属性。
inject选项应该是一个字符串数组或者是一个对象。
这对选项须要一块儿使用,以容许一个组件组件向其全部子孙后代注入一个依赖,不论组件层次有多深,而且在起上下游关系成立的时间里始终生效。
代码的使用以下图:
clipboard.png

6.EventBus:组件间的通讯

EventBus 又称为事件总线。在Vue中可使用 EventBus 来做为沟通桥梁的概念,就像是全部组件共用相同的事件中心,能够向该中心注册发送事件或接收事件,因此组件均可以上下平行地通知其余组件,但也就是太方便因此若使用不慎,就会形成难以维护的灾难,所以才须要更完善的Vuex做为状态管理中心,将通知的概念上升到共享状态层次。

7.this.$refs使用

ref:被用来给元素或子组件注册引用信息,引用信息将会注册在父组件的#refs对象上。
能够经过$refs拿到对应组件中想要获取的数据,可是,不建议使用,只有没得办法的时候,在使用。例如,须要操做dom节点的时候,或者在组件中,没法经过点击事件获取数据的时候,可使用this.$refs

clipboard.png
clipboard.png

总结

以上就是针对vue中组件的通讯方式的了解,每种通讯方式都有本身的利与弊,咱们能够根据项目的实际需求去选择适合的通讯方式,切记,滥用。而后哪里写的不对,请多多指教。由于有些方法本身在项目中使用的场景也比较少见,可能会存在误差,欢迎指出问题!!!

相关文章
相关标签/搜索