Vue 组件间如何通信
本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
云数据库 Tair(兼容Redis),内存型 2GB
简介:
Vue组件间通信是指在Vue应用中,不同组件之间传递数据和事件的方法。常用的方式有:props、自定义事件、$emit、$attrs、$refs、provide/inject、Vuex等。掌握这些方法可以实现父子组件、兄弟组件及跨级组件间的高效通信。
- 父子组件通信
- 父组件向子组件通信 - 通过属性绑定(Props)
- 原理:父组件可以将数据作为属性传递给子组件。在子组件中,通过
props
选项来接收这些数据。这是一种单向数据流,从父组件到子组件,确保了数据的可预测性和单向性,便于维护组件之间的状态。
- 示例:
- 父组件模板:
<template>
<child-component :message="parentMessage"></child-component>
</template>
这里的parentMessage
是父组件中的数据,通过:
(v - bind指令的简写)将其绑定为child - component
子组件的message
属性。
- 子组件定义:
export default {
props: {
message: String
},
mounted() {
console.log(this.message);
}
}
子组件通过props
接收message
属性,并在挂载时打印出来。props
中的message
可以指定类型(如这里的String
),还可以设置默认值、验证等其他选项。
- 子组件向父组件通信 - 通过自定义事件
- 原理:子组件通过
$emit
方法触发一个自定义事件,父组件可以在使用子组件的地方通过v - on
(简写为@
)指令来监听这个事件,并在事件处理函数中获取子组件传递的数据。
- 示例:
- 子组件模板:
<template>
<button @click="sendMessage">向父组件发送消息</button>
</template>
当点击按钮时,调用sendMessage
方法。
- 子组件方法:
export default {
methods: {
sendMessage() {
this.$emit('child - message', '这是来自子组件的消息');
}
}
}
这里通过$emit
触发了一个名为child - message
的自定义事件,并传递了一个字符串作为消息。
- 父组件模板:
<template>
<child-component @child - message="handleChildMessage"></child-component>
</template>
父组件通过@child - message
监听子组件的child - message
事件,并在handleChildMessage
方法中处理。
- 父组件方法:
export default {
methods: {
handleChildMessage(message) {
console.log(message);
}
}
}
当子组件触发事件时,父组件的handleChildMessage
方法会被调用,并接收子组件传递的消息。
- 兄弟组件通信
- 通过共同的父组件作为中介
- 原理:兄弟组件之间没有直接的通信方式,但是可以通过它们共同的父组件来传递消息。一个兄弟组件通过触发父组件的自定义事件,将消息传递给父组件,然后父组件再将消息传递给另一个兄弟组件。
- 示例:
- 假设有兄弟组件
Brother1
和Brother2
,它们有一个共同的父组件Parent
。
Brother1
组件触发事件: export default {
methods: {
sendMessageToBrother2() {
this.$emit('message - from - brother1', '这是兄弟1发送的消息');
}
}
}
- 父组件
Parent
监听Brother1
的事件并传递给Brother2
: <template>
<brother1 @message - from - brother1="handleMessageFromBrother1"></brother1>
<brother2 :message="brother2Message"></brother2>
</template>
export default {
data() {
return {
brother2Message: ''
};
},
methods: {
handleMessageFromBrother1(message) {
this.brother2Message = message;
}
}
}
Brother2
组件接收父组件传递的消息: export default {
props: {
message: String
},
mounted() {
console.log(this.message);
}
}
- 非父子、非兄弟组件通信(跨组件通信)
- 使用事件总线(Event Bus)
- 原理:创建一个独立的Vue实例作为事件总线,它可以在不同组件之间传递事件和数据。组件可以通过在这个事件总线上
$on
监听事件和$emit
触发事件来实现通信。
- 示例:
- 创建事件总线(通常在
main.js
或单独的event - bus.js
文件中): import Vue from 'vue';
export const eventBus = new Vue();
- 组件A触发事件:
import {
eventBus } from './event - bus';
export default {
methods: {
sendMessage() {
eventBus.$emit('global - message', '这是来自组件A的消息');
}
}
}
- 组件B监听事件:
import {
eventBus } from './event - bus';
export default {
mounted() {
eventBus.$on('global - message', (message) => {
console.log(message);
});
}
}
- 使用Vuex(适用于大型复杂应用)
- 原理:Vuex是一个专为Vue.js应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。
- 示例:
- 安装和配置Vuex(在
main.js
等文件中): import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);
const store = new Vuex.Store({
state: {
globalMessage: ''
},
mutations: {
setGlobalMessage(state, message) {
state.globalMessage = message;
}
}
});
new Vue({
store,
});
- 组件A提交mutation来修改状态:
export default {
methods: {
sendMessage() {
this.$store.commit('setGlobalMessage', '这是来自组件A的消息');
}
}
}
- 组件B获取状态:
export default {
computed: {
globalMessage() {
return this.$store.state.globalMessage;
}
},
mounted() {
console.log(this.globalMessage);
}
}