一、vue中组件之间存在什么样的关系?
我们可以Vue组件之间的关系为如下两类:
1)父子组件之间通信。
2)非父子组件之间通信(兄弟组件、隔代关系组件等)。
二、Vue中的组件通信方式
1)父子组件之间通信:
1. pros / $emit
父组件通过props的方式向子组件传递数据,而通过$emit 子组件可以向父组件通信。
注意:props 只可以从上一级组件传递到下一级组件(父子组件),即所谓的单向数据流。而且 props 只读,不可被修改,所有修改都会失效并警告。
子组件通过$emit触发自定义事件,$emit第二个参数为传递的数值。父组件绑定监听器获取到子组件传递过来的参数。
2. $children / $parent
vue官方的解释: $parent和$children
通过$parent和$children就可以访问组件的实例,即可以访问此组件的所有方法和data。
注意:边界情况,如在#app上拿$parent得到的是new Vue()的实例,在这实例上再拿$parent得到的是undefined,而在最底层的子组件拿$children是个空数组。并且$parent和$children的值不一样,$children 的值是数组,而$parent是个对象。
2)非父子组件之间通信
3. provide/ reject
父组件中通过provide来提供变量, 然后再子组件中通过reject来注入变量。provide / inject API 主要解决了跨级组件间的通信问题,不过它的使用场景,主要是子组件获取上级组件的状态,跨级组件间建立了一种主动提供与依赖注入的关系。
注意:不论子组件嵌套有多深, 只要调用了inject 那么就可以注入provide中的数据,而不局限于只能从当前父组件的props属性中去取数据。
4. ref / refs
ref:如果在普通的 DOM 元素上使用,引用指向的就是 DOM 元素;如果用在子组件上,引用就指向组件实例,可以通过实例直接调用组件的方法或访问数据。
5. eventBus
eventBus 又称为事件总线,在vue中可以使用它来作为沟通桥梁的概念, 就像是所有组件共用相同的事件中心,可以向该中心注册发送事件或接收事件, 所以组件都可以通知其他组件。
6. Vuex
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化. Vuex 解决了多个视图依赖于同一状态和来自不同视图的行为需要变更同一状态的问题,将开发者的精力聚焦于数据的更新而不是数据在组件之间的传递上。
Vuex各个模块:
state:用于数据的存储,是store中的唯一数据源。
getters:如vue中的计算属性一样,基于state数据的二次包装,常用于数据的筛选和多个数据的相关性计算。
mutations:类似函数,改变state数据的唯一途径,且不能用于处理异步事件。
actions:类似于mutation,用于提交mutation来改变状态,而不直接变更状态,可以包含任意异步操作。
modules:类似于命名空间,用于项目中将各个模块的状态分开定义和操作,便于维护。
7. localStorage / sessionStorage
通过window.localStorage.getItem(key)获取数据 通过window.localStorage.setItem(key,value)存储数据。
8. $attrs与 $listeners
现在我们来讨论一种情况:给出的组件关系图中A组件与D组件是隔代关系。
多级组件嵌套需要传递数据时,通常使用的方法是通过vuex。但如果仅仅是传递数据,而不做中间处理,使用 vuex 处理,未免有点大材小用。可以使用$attrs/$listeners。包含了父级作用域中不作为prop被识别 (且获取) 的特性绑定 ( class 和 style 除外)。
$attrs与$listeners是两个对象,$attrs里存放的是父组件中绑定的非 Props 属性,$listeners里存放的是父组件中绑定的非原生事件。
三、总结
常见使用场景可以分为三类:
- 父子组件通信: props; $parent / $children; ref ;
- 兄弟组件通信: eventBus ; vuex
- 跨级通信: provide / inject 、 $attrs / $listeners