logo

Vue组件通信方式一览

Example Code

下面所有描述的通讯方式可以在下面这个窗口查看测试:

props,v-on/\$emit

在官方文档中组件基础的通讯方式:

  • 父组件通过props将数据传入子组件。
  • 子组件通过 父组件监听子组件事件,子组件触发事件传递数据

vuex

当我们需要有一些全局共享数据时,如果通过组件层层传递,那将是噩梦。
此时可以通过Vuex帮助我们管理数据,Vuex通过对vm实例注入$store对象实现对这些数据的访问。
不仅如此,Vuex 还提供了模块化,数据处理加工,追踪记录数据变化等等功能。

event bus

一个vm实例,可以监听/触发事件。因此我们是用一个vm实例作为事件总线,通过这个事件总线不同组件之间只要在这个总线上注册触发事件就可以实现通信。
值得注意的一点是,注册的事件需要在组件销毁时使用vm.$off()方法进行清除,避免事件多次注册导致多次执行。

provide/inject

provide/inject 可以为所有子孙组件传递数据,类似于 Reactcontext
通过这个方法我们便可以将父组件数据向下传递,但是要注意的是这些数据并不是响应式的。
实现响应式可以通过以下两个方式:

  • 通过provide传递父组件的vm实例
  • 通过Vue.observable(Object)传递响应式数据

\$attrs/$listeners(2.4+)

当我们封装高阶组件(二次封装), 将属性/监听事件,从高阶组件传递到被封装的组件,2.4 版本前可能需要手动去获取再传递给被封装组件。
此时高阶组件和被封装组件是耦合的,当被封装组件属性变化,高阶组件也需要调整,也就是 不透明。而 $attrs/$listeners 可以解决这个问题。

\$attrs:

包含了父作用域中不作为 prop 被识别 (且获取) 的特性绑定 (class 和 style 除外)。当一个组件没有声明任何 prop 时,这里会包含所有父作用域的绑定 (class 和 style 除外),并且可以通过 v-bind=”\$attrs” 传入内部组件——在创建高级别的组件时非常有用。

\$listeners

包含了父作用域中的 (不含 .native 修饰器的) v-on 事件监听器。它可以通过 v-on=”\$listeners” 传入内部组件——在创建更高层次的组件时非常有用。

通过$attrs/$listeners我们可以更方便的透传属性以及监听事件。

\$parent/$children/ref

\$parent

一个子组件可以通过$parent来直接获取父组件的实例进一步获取数据。

\$children

一个父组件可以获取由直接子组件组成的数组实例进一步获取子组件数据。

ref

通过ref可以拿到一个组件在页面对应的DOM对象,因此就可以访问DOM对象上的属性方法。