Skip to content
登录后刷题更便捷

组件通信

难度:

组件通信一般分为以下几种情况:

  • 父子组件通信
  • 兄弟组件通信
  • 跨多层级组件通信
  • 任意组件

对于以上每种情况都有多种方式去实现,接下来就来学习下如何实现。

父子通信

父组件通过props传递数据给子组件,子组件通过emit发送事件传递数据给父组件,这两种方式是最常用的父子通信实现办法。

这种父子通信方式也就是典型的单向数据流,父组件通过props传递数据,子组件不能直接修改props, 而是必须通过发送事件的方式告知父组件修改数据。

另外这两种方式还可以使用语法糖v-model来直接实现,因为v-model默认会解析成名为valueprop和名为input的事件。这种语法糖的方式是典型的双向绑定,常用于 UI 控件上,但是究其根本,还是通过事件的方法让父组件修改数据。

当然我们还可以通过访问$parent或者$children对象来访问组件实例中的方法和数据。

另外如果你使用 Vue 2.3 及以上版本的话还可以使用$listeners.sync这两个属性。

$listeners属性会将父组件中的 (不含.native修饰器的)v-on事件监听器传递给子组件,子组件可以通过访问$listeners来自定义监听器。

.sync属性是个语法糖,可以很简单的实现子组件与父组件通信

vue
<!--父组件中-->
<input :value.sync="value" />
<!--以上写法等同于-->
<input :value="value" @update:value="(v) => (value = v)" />
<!--子组件中-->
<script>
this.$emit("update:value", 1);
</script>

兄弟组件通信

对于这种情况可以通过查找父组件中的子组件实现,也就是this.$parent.$children,在$children中可以通过组件name查询到需要的组件实例,然后进行通信。

跨多层次组件通信

对于这种情况可以使用 Vue 2.2 新增的 APIprovide / inject,虽然文档中不推荐直接使用在业务中,但是如果用得好的话还是很有用的。

假设有父组件 A,然后有一个跨多层级的子组件 B

js
// 父组件 A
export default {
  provide: {
    data: 1
  }
}
// 子组件 B
export default {
  inject: ['data'],
  mounted() {
    // 无论跨几层都能获得父组件的 data 属性
    console.log(this.data) // => 1
  }
}

任意组件

这种方式可以通过 Vuex 或者 Event Bus 解决,另外如果你不怕麻烦的话,可以使用这种方式解决上述所有的通信情况

extend 能做什么

这个 API 很少用到,作用是扩展组件生成一个构造器,通常会与$mount一起使用。

js
// 创建组件构造器
let Component = Vue.extend({
  template: "<div>test</div>",
});
// 挂载到 #app 上
new Component().$mount("#app");
// 除了上面的方式,还可以用来扩展已有的组件
let SuperComponent = Vue.extend(Component);
new SuperComponent({
  created() {
    console.log(1);
  },
});
new SuperComponent().$mount("#app");

内容仅供参考,难免有不恰当的地方,如果有问题欢迎及时反馈
部分内容来自网络,如果不慎侵犯您的权益,请联系我们,以便及时删除侵权内容