Vue.js 组件间通信指南

本文将详细介绍 Vue 中几种常用的通信方法,包括基本的 props 传递、自定义事件、事件总线、v-model 双向绑定、sync 属性修饰符、$attrs$listeners 的使用、$children$parent 的访问、provideinject 的高级应用,以及 Vuex 状态管理库的集成。

一、组件间通信最基本方式: props

props 是父组件传递给子组件的数据。在父组件中,通过在子组件标签上绑定属性并传递相应的值来传递数据;在子组件中,则需要在 props 选项中声明接收哪些属性,并在组件中使用这些属性。

注意点:

  • 确保在子组件中正确声明所有从父组件接收的 props
  • 如果 props 是对象或数组类型,应当考虑深拷贝以避免意外更改原始数据。

示例

父组件

<template>
  <child-component :message="message" />
</template>

<script>
import ChildComponent from './ChildComponent.vue';

export default {
  components: {
    ChildComponent
  },
  data() {
    return {
      message: 'Hello World!'
    }
  }
}
</script>
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.

子组件

<template>
  <div>{{ message }}</div>
</template>

<script>
export default {
  props: {
    message: String
  }
}
</script>
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.

二、组件间通信2: Vue自定义事件

除了通过 props 进行父子组件之间的通信,Vue 还提供了一种更加灵活的组件间通信方式,即自定义事件。通过自定义事件,可以让子组件向父组件发送消息,也可以让任意两个组件之间进行通信。

注意点:

  • 当使用 $emit 触发事件时,确保父组件已经监听了这个事件。
  • 事件名称应当遵循约定的命名规范,例如使用 kebab-case。

示例

子组件

<template>
  <button @click="sendMessage">发送消息</button>
</template>

<script>
export default {
  methods: {
    sendMessage() {
      this.$emit('message', 'Hello World!');
    }
  }
}
</script>
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.

父组件

<template>
  <child-component @message="handleMessage" />
</template>

<script>
import ChildComponent from './ChildComponent.vue';

export default {
  components: {
    ChildComponent
  },
  methods: {
    handleMessage(message) {
      console.log(message);
    }
  }
}
</script>
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.

三、组件间通信3: 事件总线

事件总线是一个 Vue 实例,可以用来在任意两个组件之间进行通信。事件总线可以通过 Vue 的全局事件机制来实现,即使用 $emit 方法触发一个全局事件,然后在需要监听这个事件的组件中使用 $on 方法进行监听。

注意点:

  • 事件总线是一种全局的通信方式,应当谨慎使用,以免导致组件间的耦合过高。
  • 在组件销毁时取消事件监听,以避免内存泄漏。

示例

创建全局事件总线

// event-bus.js
import Vue from 'vue';

export const eventBus = new Vue();
  • 1.
  • 2.
  • 3.
  • 4.

组件 A(发送消息)

import { eventBus } from './event-bus.js';

export default {
  methods: {
    sendMessage() {
      eventBus.$emit('message', 'Hello World!');
    }
  }
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.

组件 B(接收消息)

import { eventBus } from './event-bus.js';

export default {
  created() {
    eventBus.$on('message', message => {
      console.log(message);
    });
  },
  beforeDestroy() {
    eventBus.$off('message');
  }
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.

就先到这里啦!后续继续更新!