vue组件中的通信方式

前言

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

1.props和$emit

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

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

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

《vue组件中的通信方式》

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的结果是一个对象,里面是父组件的信息:

《vue组件中的通信方式》
$children:当前实例的子组件。例如:在父组件中打印this.$children可以获取到一个数组,这个数组里面包含其所有的子组件。

《vue组件中的通信方式》

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组件):

《vue组件中的通信方式》

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

《vue组件中的通信方式》

C组件(接收text2):

《vue组件中的通信方式》

结果展示:

《vue组件中的通信方式》

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

$listeners:包含了父作用域中的(不含.native修饰器)v-on事件监听器,它可以通过v-on=$listeners 传入内部组件–在创建更高层次的组件时sh非常有用的。
这个属性就是和$attrs时类似的,只不过是自定义事件从子组件传到父组件的使用。

《vue组件中的通信方式》

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

provide选项是一个对象或者返回一个对象的函数。该对象包含可注入其子孙的属性。
inject选项应该是一个字符串数组或者是一个对象。
这对选项需要一起使用,以允许一个组件组件向其所有子孙后代注入一个依赖,不论组件层次有多深,并且在起上下游关系成立的时间里始终生效。
代码的使用如下图:
《vue组件中的通信方式》

6.EventBus:组件间的通信

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

7.this.$refs使用

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

《vue组件中的通信方式》
《vue组件中的通信方式》

总结

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

    原文作者:栀子花
    原文地址: https://segmentfault.com/a/1190000020256036
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞