组件之间的通信是vue非常重要的一个构成部分。而不同关系的组件之间的通信方式也有所不同,今天就来梳理一下这些通信方式吧。
父子通信
组件A引入组件B作为A的组件是非常常见的一种场景,这个时候怎么实现通信呢?
父传子
父组件通过props
的方式向子组件传递。子组件接受可以是任何类型的props,举例:
父组件给子组件传了一个类型为Boolean的value,子组件接受了这个组件值生成了不同的样式。
修改传入值为true
这样就实现了父传子
子传父
子传父可以通过this.$emit
来传递一个事件,vue的官方文档中说“不应该在一个子组件的内部改变prop,如果你这样做了,vue会在浏览器的控制台中发出警告”,所以我们这里所说的子传父是将最新的值传给父组件,再由父组件传给子组件实现闭环。
同样是刚才的例子,我们希望能通过点击事件来改变class的值实现样式的改变。
子组件增加一个点击事件,click的时候触发this.$emit('update:value',newValue)
,把最新的值返回给父组件。同时将父组件传递的prop一个名字,用on监听返回的值。
这个时候不仅实现了子传父,也完成了父子双向绑定。
不相关的组件
EventBus
可以通过构造一个新的Vue实例Event,使用Event.$emit
和Event.$on
来实现通信,爷孙通信和其他跨级通信可以使用这种方法。
类似于上面子传父的方法,注意emit和on的第一个参数事件名保持一致。
但是当组件之间的通信比较多时,使用这种方法难以分辨事件的触发来自于哪里,比较麻烦,这个时候我们可以使用Vue官方开发的状态管理模式和库Vuex。
Vuex
Vuex可以全局拥有一个存放数据修改数据。具体有以下几个部分。
- Store 是一个大容器,包含了以下所有内容
- State 全局存储状态并且可以使用
this.$store
全局调用.附带一个mapState函数辅助生成计算属性。 - Getter state的对象读取方法,getter接受state作为其第一个参数,不改变state原本的值但可以对其做计算,官方文档说可以认为是store的计算属性。附带一个mapGetters辅助函数将store 的getter映射到局部。
- Mutation 用于同步提交状态变更,需要用
commit
来调用。同时可以接受传入其他的参数,放在payload中。 - Aciton 用于异步提交状态变更,提交的是mutation,不直接变更状态。
- Module 模块化,方便代码维护和管理
provide&inject
允许一个祖先组件向其所有子孙后代注入一个依赖,不论组件层次有多深,并在起上下游关系成立的时间里始终生效。 祖先组件中通过provider来提供变量,然后在子孙组件中通过inject来注入变量,解决了跨级组件间的通信问题。 不过它的使用场景,主要是子组件获取上级组件的状态,跨级组件间建立了一种主动提供与依赖注入的关系。
总结
1.父子组件
父传子,儿子接受一个props;子传父,this.$emit 事件。
2,爷孙组件
使用provide和inject来通信
3,任意组件
使用eventbus 创建一个新的vue实例emit
使用vuex