最近一轮的面试结束了,没有特别满意的公司,就想着静下心来好好地把vue相关的基础知识整理一下。这周的技术周报就把vue中组件通信的几种方式整理下。本文主要参考Vue中的8中组件通信方式,各种方式的详细案例都可去这边文章中查找。本文只是做一个整理。
首先,vue中组件之间的关系主要分为父子、非父子(隔代、兄弟)。本文提到的几种组件通信方法分别为:props/$emit、$children/$parent、provide/inject、ref、eventBus、vuex、localStorage/sessionStorage、$attrs/$listeners.
一、props/$emit
父组件通过props的方式向子组件传递数据,而子组件通过$emit可以向父组件通信。
注意: prop 只可以从上一级组件传递到下一级组件(父子组件),即所谓的单向数据流。而且 prop 只读,不可被修改,所有修改都会失效并警告。
$emit绑定一个自定义事件, 当这个语句被执行时, 就会将参数arg传递给父组件,父组件通过v-on监听并接收参数。
二、$children/$parent
vue官方对$parent的解释是:
注意:边界情况,如在#app上拿$parent得到的是new Vue()的实例,在这实例上再拿$parent得到的是undefined,而在最底层的子组件拿$children是个空数组。也要注意得到$parent和$children的值不一样,$children 的值是数组,而$parent是个对象。
三、 provide/inject
provide/ inject 是vue2.2.0新增的api, 简单来说就是父组件中通过provide来提供变量, 然后再子组件中通过inject来注入变量。
注意:不论子组件嵌套有多深, 只要调用了inject 那么就可以注入provide中的数据,而不局限于只能从当前父组件的props属性中回去数据。
四、ref/refs
如果在普通的 DOM 元素上使用,ref的引用指向的就是 DOM 元素;如果用在子组件上,ref的引用就指向组件实例,可以通过实例直接调用组件的方法或访问数据。
具体实例,参见原文。
五、eventBus
eventBus 又称为事件总线,在vue中可以使用它来作为沟通桥梁的概念, 就像是所有组件共用相同的事件中心,可以向该中心注册发送事件或接收事件, 所以组件都可以通知其他组件。
注意:eventBus也有不方便之处, 当项目较大,就容易造成难以维护的灾难。
具体使用方法也参见原文。
六、Vuex
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。
Vuex 解决了多个视图依赖于同一状态和来自不同视图的行为需要变更同一状态的问题,将开发者的精力聚焦于数据的更新而不是数据在组件之间的传递上。
vuex的各个模块:
- state:用于数据的存储,是store中的唯一数据源
- getters:如vue中的计算属性一样,基于state数据的二次包装,常用于数据的筛选和多个数据的相关性计算
- mutations:类似函数,改变state数据的唯一途径,且不能用于处理异步事件
- actions:类似于mutation,用于提交mutation来改变状态,而不直接变更状态,可以包含任意异步操作
- modules:类似于命名空间,用于项目中将各个模块的状态分开定义和操作,便于维护
具体使用方法参见vuex官方文档
。
七、localStorage/sessionStorage
这种通信比较简单,缺点是数据和状态比较混乱,不太容易维护。
通过window.localStorage.getItem(key)获取数据,
通过window.localStorage.setItem(key,value)存储数据。
注意:用JSON.parse() / JSON.stringify() 做数据格式转换 localStorage / sessionStorage可以结合vuex, 实现数据的持久保存,同时使用vuex解决数据和状态混乱问题。
八、$attrs/$listeners
在vue2.4中,为了解决跨级通信的需求,引入了$attrs 和$listeners , 新增了inheritAttrs 选项。 在版本2.4以前,默认情况下,父作用域中不作为 prop 被识别 (且获取) 的特性绑定 (class 和 style 除外),将会“回退”且作为普通的HTML特性应用在子组件的根元素上。
总结:
上述组件通信的方法可以按以下几种场景分类:
父子组件通信: props、$parent / $children、 ref ;
兄弟组件通信: eventBus 、 vuex;
跨级通信: provide / inject 、$attrs /\ $listeners。
参考资料:
- Vue中的8中组件通信方式