VUE组件间的通信方式都有哪些

Vue.js 是一个用于构建用户界面的渐进式框架。在 Vue.js 中,组件是构成应用的基本单元,而组件之间的通信则是实现复杂功能的关键。

组件间通信的概念

vue中每一个.vue文件我们都可以视为一个组件,通信指的是组件通过某种方式来传递信息以达到某个目的。

组件间通信的分类

在 Vue.js 中,组件之间的通信方式有多种,根据组件的关系(父子、兄弟或跨层级),主要有以下几种:

好的,下面是针对每种通信方式的示例代码:

1. 父子组件通信

Props Down

父组件:

html 复制代码
<template>
  <div>
    <child-component :message="parentMessage"></child-component>
  </div>
</template>

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

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

子组件:

html 复制代码
<template>
  <div>{{ message }}</div>
</template>

<script>
export default {
  props: ['message']
}
</script>
$emit Up

子组件:

html 复制代码
<template>
  <button @click="sendMessage">Click me</button>
</template>

<script>
export default {
  methods: {
    sendMessage() {
      this.$emit('send-message', 'Hello from Child');
    }
  }
}
</script>

父组件:

html 复制代码
<template>
  <div>
    <child-component @send-message="receiveMessage"></child-component>
  </div>
</template>

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

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

2. 兄弟组件通信

Event Bus

创建事件总线:

javascript 复制代码
import Vue from 'vue';
export const EventBus = new Vue();

兄弟组件 A:

html 复制代码
<template>
  <button @click="sendMessage">Send Message</button>
</template>

<script>
import { EventBus } from './event-bus.js';

export default {
  methods: {
    sendMessage() {
      EventBus.$emit('send-message', 'Hello from Component A');
    }
  }
}
</script>

兄弟组件 B:

html 复制代码
<template>
  <div>{{ receivedMessage }}</div>
</template>

<script>
import { EventBus } from './event-bus.js';

export default {
  data() {
    return {
      receivedMessage: ''
    };
  },
  created() {
    EventBus.$on('send-message', (message) => {
      this.receivedMessage = message;
    });
  },
  beforeDestroy() {
    EventBus.$off('send-message');
  }
}
</script>
Vuex

创建 Vuex store:

javascript 复制代码
import Vue from 'vue';
import Vuex from 'vuex';

Vue.use(Vuex);

export default new Vuex.Store({
  state: {
    sharedMessage: 'Shared state in Vuex'
  },
  mutations: {
    updateMessage(state, message) {
      state.sharedMessage = message;
    }
  }
});

兄弟组件 A:

html 复制代码
<template>
  <button @click="updateMessage">Update Message</button>
</template>

<script>
import { mapMutations } from 'vuex';

export default {
  methods: {
    ...mapMutations(['updateMessage']),
    updateMessage() {
      this.updateMessage('Message updated by Component A');
    }
  }
}
</script>

兄弟组件 B:

html 复制代码
<template>
  <div>{{ sharedMessage }}</div>
</template>

<script>
import { mapState } from 'vuex';

export default {
  computed: {
    ...mapState(['sharedMessage'])
  }
}
</script>

3. 跨层级组件通信

provide / inject

祖辈组件:

html 复制代码
<template>
  <div>
    <child-component></child-component>
  </div>
</template>

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

export default {
  components: {
    ChildComponent
  },
  provide() {
    return {
      injectedMessage: 'Injected Message'
    };
  }
}
</script>

子组件:

html 复制代码
<template>
  <div>{{ injectedMessage }}</div>
</template>

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

4. 全局事件( r o o t 、 root、 root、parent)

父组件:

html 复制代码
<template>
  <div>
    <child-component></child-component>
  </div>
</template>

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

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

子组件:

html 复制代码
<template>
  <button @click="sendMessage">Send Global Message</button>
</template>

<script>
export default {
  methods: {
    sendMessage() {
      this.$parent.handleGlobalEvent('Message from Child via $parent');
    }
  }
}
</script>

5. attrs 和 listeners

父组件:

html 复制代码
<template>
  <div>
    <custom-element some-attr="value" @some-event="handleEvent"></custom-element>
  </div>
</template>

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

export default {
  components: {
    CustomElement
  },
  methods: {
    handleEvent(eventData) {
      console.log(eventData);
    }
  }
}
</script>

自定义元素:

html 复制代码
<template>
  <div :style="{ color: color }">{{ message }}</div>
</template>

<script>
export default {
  inheritAttrs: false,
  mounted() {
    console.log(this.$attrs); // 查看所有未显式绑定的属性
    console.log(this.$listeners); // 查看所有未显式绑定的监听器
  }
}
</script>

6. $ref 直接访问子组件实例

父组件:

html 复制代码
<template>
  <div>
    <child-component ref="child"></child-component>
    <button @click="callChildMethod">Call Child Method</button>
  </div>
</template>

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

export default {
  components: {
    ChildComponent
  },
  methods: {
    callChildMethod() {
      this.$refs.child.childMethod();
    }
  }
}
</script>

子组件:

html 复制代码
<template>
  <div>
    <!-- 子组件模板 -->
  </div>
</template>

<script>
export default {
  methods: {
    childMethod() {
      console.log('Called child method');
    }
  }
}
</script>

每种通信方式适用于不同场景,需根据需求选择合适的方法。

相关推荐
小高0071 分钟前
📈前端图片压缩实战:体积直降 80%,LCP 提升 2 倍
前端·javascript·面试
BillKu12 分钟前
vue3+element-plus 输入框el-input设置背景颜色和字体颜色,样式效果等同于不可编辑的效果
前端·javascript·vue.js
每天学习一丢丢14 分钟前
Spring Boot + Vue 项目用宝塔面板部署指南
vue.js·spring boot·后端
springfe010123 分钟前
vue3组件 - 大文件上传
前端·vue.js
NeilNiu41 分钟前
开源AI工具Midscene.js
javascript·人工智能·开源
好好好明天会更好1 小时前
uniapp项目中小程序的生命周期
前端·vue.js
Warren981 小时前
软件测试-Selenium学习笔记
java·javascript·笔记·学习·selenium·测试工具·安全
萌萌哒草头将军1 小时前
有了它 ,我彻底告别了 try-finally 🔥🔥🔥
前端·javascript·vue.js
老虎06272 小时前
JavaWeb前端02(JavaScript)
开发语言·前端·javascript
anyup2 小时前
🔥🔥 10 天 Star 破百!uView Pro 文档也开源啦:完全免费、无广告、高效上手
前端·vue.js·uni-app