在Vue中,组件间通信主要的几种方式

143 阅读2分钟

 在Vue 2中,组件间通信主要有以下几种方式:

  1. 父子组件通信:props 和 events

  2. 子父组件通信:使用 $emit 和 $on

  3. 兄弟组件通信:使用事件总线或Vuex

  4. 跨多层级组件通信:使用事件总线或Vuex

1.父子组件通信(Props 和 Events)

1.Props(属性) :

  1. 父组件通过props向子组件传递数据。

  2. 子组件通过props接收父组件传递的数据。

2. events(事件) :

  1. 子组件可以通过$emit方法触发事件,并将数据传递给父组件。

  2. 父组件通过在子组件上使用@或v-on指令监听事件,从而接收子组件传递的数据。

父组件:

<template>
  <ChildComponent :parentData="data" @childEvent="handleChildEvent" />
</template>
 
<script>
import ChildComponent from './ChildComponent.vue';
 
export default {
  components: {
    ChildComponent
  },
  data() {
    return {
      data: '父组件'
    };
  },
  methods: {
    handleChildEvent(payload) {
      // 处理子组件事件
    }
  }
};
</script>

子组件:

<template>
  <button @click="sendToParent">子组件</button>
</template>
 
<script>
export default {
  props: ['parentData'],
  methods: {
    sendToParent() {
      this.$emit('childEvent', '子组件');
    }
  }
};
</script>

2.子父组件通信($emit 和 $on

1. $on (事件):

        1. 监听实例上的自定义事件;事件由 $emit 触发;回调函数会接受触发函数传入的参数。

2. $emit (事件):

        1. 子组件给父组件传值触发的实例事件。

子组件:

<template>
  <button @click="sendToParent">子组件</button>
</template>
 
<script>
export default {
  methods: {
    sendToParent() {
      this.$emit('custom-event', '子组件');
    }
  }
};
</script>

父组件:

<template>
  <ChildComponent @custom-event="handleCustomEvent" />
</template>
 
<script>
import ChildComponent from './ChildComponent.vue';
 
export default {
  components: {
    ChildComponent
  },
  methods: {
    handleCustomEvent(payload) {
      // 处理自定义事件
    }
  }
};
</script>

3.兄弟组件通信(事件总线)

事件总线是一种简单的发布-订阅模式,它允许你在组件间发送和接收事件。你可以在一个文件中创建一个 Vue 实例,并将其作为事件总线,在所有需要通信的组件中导入并使用它。

第一种方式

先创建一个js文件 “EventBus.js”内容如下

import Vue from 'vue';
export const EventBus = new Vue();

在需要通信的地方导入EventBus.js文件

import { EventBus} from './EventBus.js';

第二种方式

挂载到Vue原型上

Vue.prototype.$EventBus = new Vue()

下面是具体使用方式

1. ComponentA.vue

<template>
  <button @click="sendToComponentB">Send to Component B</button>
</template>
 
<script>
import { EventBus } from './EventBus.js';
 
export default {
  methods: {
    sendToComponentB() {
//     这是第一种方式
      EventBus.$emit('data-for-b', '要传递的信息');
//     这是第二种方式
      this.$EventBus.$emit('data-for-b', '要传递的信息')

    }
  }
};
</script>

2. ComponentB.vue

<template>
  <div>{{ dataFromA }}</div>
</template>
 
<script>
import { EventBus } from './EventBus.js';
 
export default {
  data() {
    return {
      dataFromA: ''
    };
  },
 // 组件创建后生命周期钩子
  created() {
    // 监听EventBus上的'data-for-b'事件,当该事件被触发时,调用this.receiveData方法
    //第一种方式
    EventBus.$on('data-for-b', this.receiveData);
    //第二种方式
    this.$EventBus.$on('data-for-b',(n1)=>{})

  },
  // 组件销毁前生命周期钩子
  beforeDestroy() {
    // 在组件销毁前,取消监听EventBus上的'data-for-b'事件
    // 这样做是为了避免内存泄漏,确保组件销毁后不会再有事件处理函数被调用
    //第一种方式
    EventBus.$off('data-for-b', this.receiveData);
    //第二种方式
    this.$EventBus.$off('data-for-b',this.receiveData)
  },
  methods: {
    receiveData(payload) {
      this.dataFromA = payload;
    }
  }
};
</script>

4. 跨多层级组件通信(Vuex)

在Vue.js中,使用Vuex进行跨多层级组件通信时,可以通过在Vuex的state中定义全局状态,并通过mutations或actions来改变这些状态。这样,任何组件都可以通过获取state中的数据,或触发mutations/actions来进行通信。

1. 先安装并设置Vuex

npm install vuex --save

2. 在Vue实例中引入并配置store:

// main.js
import Vue from 'vue';
import App from './App.vue';
// 引入Vuex的store(状态管理库)
import store from './store';
 
new Vue({
  store,
  render: h => h(App)
}).$mount('#app');

3. 在项目中创建一个Vuex store

// store.js
import Vue from 'vue';
import Vuex from 'vuex';
 
Vue.use(Vuex);
 
export default new Vuex.Store({
  state: {
    globalData: 'initial value'
  },
  // mutations对象包含了同步地改变state的方法
  // 注意:mutations必须是同步函数
  mutations: {
   // 它接收state作为第一个参数,以及要更新的新数据newData作为第二个参数
    updateGlobalData(state, newData) {
    // 更新state中的globalData为newData
      state.globalData = newData;
    }
  },
  // actions对象包含了异步操作,可以包含任意异步逻辑
  // actions通过提交mutations来改变state,而不是直接改变state
  actions: {
    // 它接收一个包含commit方法的上下文对象作为第一个参数
    // 以及要更新的新数据newData作为第二个参数
    updateGlobalData({ commit }, newData) {
     // 提交updateGlobalData mutation来更新state
      commit('updateGlobalData', newData);
    }
  }
});

4. 在组件中使用Vuex状态和方法

<template>
  <div>
    {{ $store.state.globalData }}
    <button @click="updateData('new value')">Update</button>
  </div>
</template>
 
<script>
export default {
  methods: {
    updateData(newData) {
      // 使用mutation直接更新数据
      this.$store.commit('updateGlobalData', newData);
      
      // 或者使用action来更新数据
      this.$store.dispatch('updateGlobalData', newData);
    }
  }
};
</script>

制作不易 请各位看官老爷们点赞 收藏加关注哦