第二阶段:Vue 组件化开发(第 20天)

兄弟组件通信方案详解

方案一:通过父组件中转

这是最直接的方式,适用于兄弟组件有共同父组件且嵌套层级不深的场景。

  1. 原理
    • 子组件 A 通过 $emit 触发自定义事件,将数据传递给父组件。
    • 父组件监听该事件,接收数据并更新自身状态(如 data)。
    • 父组件通过 props 将数据传递给子组件 B。
  2. 示例代码
vue 复制代码
<!-- ParentComponent.vue -->
<template>
  <div>
    <ChildA @data-from-A="handleDataFromA" />
    <ChildB :message="messageForB" />
  </div>
</template>

<script>
export default {
  data() {
    return {
      messageForB: ""
    };
  },
  methods: {
    handleDataFromA(data) {
      this.messageForB = data; // 父组件接收数据并更新
    }
  }
};
</script>

<!-- ChildA.vue -->
<template>
  <button @click="sendData">传递数据</button>
</template>

<script>
export default {
  methods: {
    sendData() {
      this.$emit("data-from-A", "来自A的数据"); // 触发事件并传递数据
    }
  }
};
</script>

<!-- ChildB.vue -->
<template>
  <div>{{ message }}</div>
</template>

<script>
export default {
  props: ["message"] // 通过props接收父组件传递的数据
};
</script>

方案二:使用事件总线(Event Bus)

适用于组件层级较深或跨层级通信的场景,避免逐层传递的繁琐。

  1. 原理
    • 创建全局事件总线(一个空的 Vue 实例)。
    • 子组件 A 通过 eventBus.$emit() 触发事件并传递数据。
    • 子组件 B 通过 eventBus.$on() 监听事件并接收数据。
  2. 示例代码
js 复制代码
// event-bus.js
import Vue from "vue";
export const eventBus = new Vue();
vue 复制代码
<!-- ChildA.vue -->
<template>
  <button @click="sendData">通过总线传递</button>
</template>

<script>
import { eventBus } from "./event-bus";
export default {
  methods: {
    sendData() {
      eventBus.$emit("data-event", "总线数据"); // 触发全局事件
    }
  }
};
</script>

<!-- ChildB.vue -->
<template>
  <div>{{ busMessage }}</div>
</template>

<script>
import { eventBus } from "./event-bus";
export default {
  data() {
    return {
      busMessage: ""
    };
  },
  mounted() {
    eventBus.$on("data-event", data => {
      this.busMessage = data; // 监听事件并更新数据
    });
  },
  beforeDestroy() {
    eventBus.$off("data-event"); // 组件销毁时移除监听
  }
};
</script>

方案三:使用 Vuex

适用于中大型项目,需要集中管理多个组件共享状态的场景。

  1. 原理
    • 定义全局状态(如 store.state.message)。
    • 子组件 A 通过 this.$store.commit() 提交 mutation 修改状态。
    • 子组件 B 通过 this.$store.state.message 或计算属性获取状态。
  2. 简要实现
js 复制代码
// store.js
import Vuex from "vuex";
export default new Vuex.Store({
  state: {
    message: ""
  },
  mutations: {
    setMessage(state, payload) {
      state.message = payload; // 修改状态
    }
  }
});
vue 复制代码
<!-- ChildA.vue -->
<script>
export default {
  methods: {
    sendData() {
      this.$store.commit("setMessage", "Vuex数据"); // 提交mutation
    }
  }
};
</script>

<!-- ChildB.vue -->
<template>
  <div>{{ message }}</div>
</template>

<script>
export default {
  computed: {
    message() {
      return this.$store.state.message; // 获取状态
    }
  }
};
</script>

总结与选择建议

方案 适用场景 优点 缺点
父组件中转 简单场景,组件层级浅 无需额外工具,逻辑清晰 嵌套深时传递繁琐
事件总线(Event Bus) 跨层级通信,小型项目 解耦组件,灵活 事件名需全局管理,易内存泄漏
Vuex 中大型项目,状态共享频繁 集中管理状态,可追踪变化 学习成本高,略重

实际选择

  • 简单功能(如按钮触发更新)优先用 方案一
  • 跨组件/非父子通信用 方案二,注意及时销毁事件监听。
  • 复杂状态逻辑(如用户登录信息共享)用 方案三
相关推荐
我爱加班、、3 分钟前
Websocket能携带token过去后端吗
前端·后端·websocket
AAA阿giao3 分钟前
从零拆解一个 React + TypeScript 的 TodoList:模块化、数据流与工程实践
前端·react.js·ui·typescript·前端框架
杨超越luckly9 分钟前
HTML应用指南:利用GET请求获取中国500强企业名单,揭秘企业增长、分化与转型的新常态
前端·数据库·html·可视化·中国500强
一 乐25 分钟前
校园二手交易|基于springboot + vue校园二手交易系统(源码+数据库+文档)
java·数据库·vue.js·spring boot·后端
科技D人生36 分钟前
Vue.js 学习总结(20)—— Vue-Office 实战:word、pdf、excel、ppt 多种文档的在线预览
vue.js·word·vue-pdf·stylesheet·docx-preview·vue-office
vx1_Biye_Design37 分钟前
基于Spring Boot+Vue的学生管理系统设计与实现-计算机毕业设计源码46223
java·vue.js·spring boot·spring·eclipse·tomcat·maven
vx_Biye_Design38 分钟前
基于Spring Boot+vue的湖北旅游景点门票预约平台的设计--毕设附源码29593
java·vue.js·spring boot·spring cloud·servlet·eclipse·课程设计
hedley(●'◡'●)38 分钟前
基于cesium和vue的大疆司空模仿程序
前端·javascript·vue.js·python·typescript·无人机
qq5_81151751540 分钟前
web城乡居民基本医疗信息管理系统信息管理系统源码-SpringBoot后端+Vue前端+MySQL【可直接运行】
前端·vue.js·spring boot
百思可瑞教育41 分钟前
构建自己的Vue UI组件库:从设计到发布
前端·javascript·vue.js·ui·百思可瑞教育·北京百思教育