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>

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

相关推荐
漂流瓶jz2 小时前
Webpack如何实现万物皆可import?loader的使用/配置/手写实践
前端·javascript·webpack
ZC跨境爬虫2 小时前
跟着 MDN 学CSS day_41:显式轨道、隐式网格与区域命名放置
前端·javascript·css·ui·交互
Moment4 小时前
长上下文会最终杀死 Rag 吗?
前端·javascript·后端
kyriewen5 小时前
大文件上传最全指南:分片、断点续传、秒传,一篇就够了
前端·javascript·面试
我叫黑大帅6 小时前
解决聊天页内部滚轮改为页面滚动问题
javascript·后端·面试
新酱爱学习6 小时前
手搓 10 个 Skill 后,我把重复劳动收敛成了一套零依赖 CLI 工具
前端·javascript·人工智能
罗超驿7 小时前
13.JavaScript 新手入门指南:语法、变量、流程控制全解析
开发语言·javascript
ct9787 小时前
Three.js 性能优化(测量-定位-优化)
javascript·性能优化·three
研☆香7 小时前
es6新特性功能介绍(一)
前端·ecmascript·es6
陈_杨7 小时前
鸿蒙开发-疾阅App阅读训练功能技术解析
前端·javascript