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>

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

相关推荐
艾小码1 分钟前
还在被超长列表卡到崩溃?3招搞定虚拟滚动,性能直接起飞!
前端·javascript·react.js
前端康师傅6 分钟前
JavaScript 作用域常见问题及解决方案
前端·javascript
我是日安8 分钟前
从零到一打造 Vue3 响应式系统 Day 9 - Effect:调度器实现与应用
前端·vue.js
Mintopia20 分钟前
🚀 Next.js 全栈 E2E 测试:Playwright vs Cypress
前端·javascript·next.js
原生高钙20 分钟前
JS设计模式指南
前端·javascript
Mintopia27 分钟前
⚡ WebAssembly 如何加速 AIGC 模型在浏览器中的运行效率?
前端·javascript·aigc
断竿散人33 分钟前
乾坤微前端框架的沙箱技术实现原理深度解析
前端·javascript·前端框架
uhakadotcom36 分钟前
在python中,使用conda,使用poetry,使用uv,使用pip,四种从效果和好处的角度看,有哪些区别?
前端·javascript·面试
鹏多多39 分钟前
深入解析vue的keep-alive缓存机制
前端·javascript·vue.js
吃饺子不吃馅1 小时前
为什么SnapDOM 比 html2canvas截图要快?
前端·javascript·面试