深入理解 Vue 3 元件通訊

最小生成树發表於2024-07-18

在 Vue 3 中,元件通訊是一個關鍵的概念,它允許我們在元件之間傳遞資料和事件。本文將介紹幾種常見的 Vue 3 元件通訊方法,包括 propsemitsprovideinject、事件匯流排以及 Vuex 狀態管理。

1. 使用 propsemits 進行父子元件通訊

props 傳遞資料

props 是父元件向子元件傳遞資料的一種機制。在子元件中,透過定義 props 屬性來接收父元件傳遞的資料。

父元件 (ParentComponent.vue):

<template>
  <ChildComponent :message="parentMessage" />
</template>

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

export default {
  components: {
    ChildComponent
  },
  data() {
    return {
      parentMessage: 'Hello from Parent Component!'
    };
  }
};
</script>

子元件 (ChildComponent.vue):

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

<script>
export default {
  props: {
    message: {
      type: String,
      required: true
    }
  }
};
</script>

emits 傳遞事件

子元件可以透過 $emit 方法向父元件傳送事件,從而實現從子元件向父元件傳遞資訊。

子元件 (ChildComponent.vue):

<template>
  <button @click="sendMessage">Send Message</button>
</template>

<script>
export default {
  emits: ['messageSent'],
  methods: {
    sendMessage() {
      this.$emit('messageSent', 'Hello from Child Component!');
    }
  }
};
</script>

父元件 (ParentComponent.vue):

<template>
  <ChildComponent @messageSent="handleMessage" />
</template>

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

export default {
  components: {
    ChildComponent
  },
  methods: {
    handleMessage(message) {
      console.log(message);
    }
  }
};
</script>

2. 使用 provideinject 進行祖孫元件通訊

provideinject 允許祖父元件和孫元件之間進行通訊,而不需要透過中間的父元件傳遞資料。

祖父元件 (GrandparentComponent.vue):

<template>
  <ParentComponent />
</template>

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

export default {
  components: {
    ParentComponent
  },
  provide() {
    return {
      grandparentMessage: 'Hello from Grandparent Component!'
    };
  }
};
</script>

孫元件 (GrandchildComponent.vue):

<template>
  <div>{{ grandparentMessage }}</div>
</template>

<script>
export default {
  inject: ['grandparentMessage']
};
</script>

3. 使用事件匯流排進行兄弟元件通訊

事件匯流排是一種常見的用於兄弟元件通訊的方法,通常使用 Vue 例項作為事件匯流排。

事件匯流排 (eventBus.js):

import { reactive } from 'vue';

const eventBus = reactive({});
export default eventBus;

元件 A (ComponentA.vue):

<template>
  <button @click="sendMessage">Send Message to Component B</button>
</template>

<script>
import eventBus from './eventBus.js';

export default {
  methods: {
    sendMessage() {
      eventBus.message = 'Hello from Component A!';
    }
  }
};
</script>

元件 B (ComponentB.vue):

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

<script>
import { reactive, toRefs } from 'vue';
import eventBus from './eventBus.js';

export default {
  setup() {
    const state = reactive({
      message: ''
    });

    state.message = eventBus.message;

    return {
      ...toRefs(state)
    };
  }
};
</script>

相關文章