vue 开发中常用跨层级传参方法

465 阅读1分钟

$parent

<google-map>
  <google-map-markers v-bind:places="iceCreamShops"></google-map-markers>
</google-map>

这个 <google-map> 组件可以定义一个 map property,所有的子组件都需要访问它。在这种情况下 <google-map-markers> 可能想要通过类似 this.$parent.getMap 的方式访问那个地图,以便为其添加一组标记。你可以在查阅codesandbox.io/s/github/vu…模式。

请留意,尽管如此,通过这种模式构建出来的那个组件的内部仍然是容易出现问题的。比如,设想一下我们添加一个新的 <google-map-region> 组件,当 <google-map-markers> 在其内部出现的时候,只会渲染那个区域内的标记:

<google-map>
  <google-map-region v-bind:shape="cityBoundaries">
    <google-map-markers v-bind:places="iceCreamShops"></google-map-markers>
  </google-map-region>
</google-map>

那么在 <google-map-markers> 内部你可能发现自己需要一些类似这样的 hack:

var map = this.$parent.map || this.$parent.$parent.map

使用 $parent property 无法很好的扩展到更深层级的嵌套组件上。这也是依赖注入的用武之地,它用到了两个新的实例选项:provideinject

provide 选项允许我们指定我们想要提供给后代组件的数据/方法。在这个例子中,就是 <google-map> 内部的 getMap 方法:

provide: function () {
  return {
    getMap: this.getMap
  }
}

然后在任何后代组件里,我们都可以使用 inject 选项来接收指定的我们想要添加在这个实例上的 property:

inject: ['getMap']

相比 $parent 来说,这个用法可以让我们在

任意

后代组件中访问 getMap,而不需要暴露整个

codesandbox.io/s/github/vu…

监听

现在,你已经知道了 $emit 的用法,它可以被 v-on 侦听,但是 Vue 实例同时在其事件接口中提供了其它的方法。我们可以:

  • 通过 $on(eventName, eventHandler) 侦听一个事件
  • 通过 $once(eventName, eventHandler) 一次性侦听一个事件
  • 通过 $off(eventName, eventHandler) 停止侦听一个事件

转自vue官方文档