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>

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

相关推荐
老家的回忆16 分钟前
jsPDF和html2canvas生成pdf,组件用的elementplus,亲测30多页,20s实现
前端·vue.js·pdf·html2canvas·jspdf
hackchen1 小时前
从0到1解锁Element-Plus组件二次封装El-Dialog动态调用
前端·vue.js·elementui
用户7579419949701 小时前
Vue响应式原理推导过程
vue.js·响应式设计
黄瓜沾糖吃1 小时前
大佬们指点一下倒计时有什么问题吗?
前端·javascript
温轻舟1 小时前
3D词云图
前端·javascript·3d·交互·词云图·温轻舟
浩龙不eMo1 小时前
✅ Lodash 常用函数精选(按用途分类)
前端·javascript
爱分享的程序员2 小时前
前端面试专栏-算法篇:17. 排序算法
前端·javascript·node.js
pe7er2 小时前
使用 Vue 官方脚手架创建项目时遇到 Node 18 报错问题的排查与解决
前端·javascript·vue.js
pe7er2 小时前
使用 types / typings 实现全局 TypeScript 类型定义,无需 import/export
前端·javascript·vue.js
islandzzzz3 小时前
(第二篇)HMTL+CSS+JS-新手小白循序渐进案例入门
前端·javascript·css·html