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>

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

相关推荐
kyriewen2 小时前
我用 Codex 重写了同事维护三年的代码,他没说谢谢——而是找了领导
前端·javascript·ai编程
OpenTiny社区2 小时前
从零开发 AI 聊天页要两周?试试这款 Vue3 垂直对话组件库 TinyRobot,直接开箱即用
前端·vue.js·github
铁皮饭盒2 小时前
S3已成为文件存储标准,阿里/腾讯/华为云都支持,Bun率先原生支持
前端·javascript·后端
Cobyte2 小时前
22.Vue Vapor 组件 props 的实现
前端·javascript·vue.js
浮生望4 小时前
JS字符串与回文算法:从包装类到双指针的面试进阶之路
javascript·算法
疯狂的魔鬼4 小时前
一套 Schema 驱动四视图:记 useCrudSchemas 的设计与实践
前端·javascript·typescript
白雾茫茫丶5 小时前
探索 Nuxt.js 全栈能力:用 Better-Auth 打造类型安全的 RBAC 权限系统
前端·vue.js·nuxt.js
weedsfly5 小时前
栈和堆:JavaScript 内存的“旅馆”和“仓库”
前端·javascript·面试
向阳而生6605 小时前
文件上传也能玩出花?Vue3 教你优雅实现“选择文件”和“选择文件夹”🚀
vue.js
3630458415 小时前
Signal 带来的架构问题思考
前端·vue.js