Vue实现组件间通信的11种方式

简介: 前端-实践

原文合集地址如下,有需要的朋友可以关注

本文地址

合集地址

组件之间的通信是指不同组件之间在共享数据、传递消息或触发事件等方面进行交流和协作的过程。在应用程序中,不同的组件可能需要相互传递数据、共享状态、触发动作或响应事件等,以实现组件之间的协调和交互。

vue组件之间的通信可以有多种形式和方式,常见的包括:

  1. Props / 组件属性: 通过父组件向子组件传递数据,将数据作为组件的属性(props)传递给子组件。子组件通过接收这些属性来访问和使用父组件传递的数据。
<!-- 父组件 -->
<template>
  <div>
    <child-component :message="parentMessage" />
  </div>
</template>

<script>
import ChildComponent from './ChildComponent.vue';

export default {
   
  components: {
   
    ChildComponent
  },
  data() {
   
    return {
   
      parentMessage: 'Hello from parent'
    };
  }
}
</script>

<!-- 子组件 ChildComponent.vue -->
<template>
  <div>
    <p>{
   {
    message }}</p>
  </div>
</template>

<script>
export default {
   
  props: ['message']
}
</script>
  1. Custom Events / 自定义事件: 子组件可以触发自定义事件,并通过事件传递数据给父组件或其他监听该事件的组件。父组件或其他组件通过监听并处理这些自定义事件来接收传递的数据。
<!-- 父组件 -->
<!-- 子组件 ChildComponent.vue -->
<template>
  <div>
    <button @click="sendMessage">Send Message</button>
  </div>
</template>

<script>
export default {
   
  methods: {
   
    sendMessage() {
   
      this.$emit('custom-event', 'Hello from child');
    }
  }
}
</script>

<!-- 父组件 -->
<template>
  <div>
    <child-component @custom-event="handleEvent" />
  </div>
</template>

<script>
import ChildComponent from './ChildComponent.vue';

export default {
   
  components: {
   
    ChildComponent
  },
  methods: {
   
    handleEvent(message) {
   
      console.log(message); // 输出:Hello from child
    }
  }
}
</script>
  1. Event Bus / 事件总线: 使用一个全局事件总线来实现组件之间的通信。不同的组件可以通过事件总线来订阅和发布事件,实现数据的传递和通知。需要先下载依赖mtt
npm install mitt
// 或者
yarn add mitt
// EventBus.js
import mitt from 'mitt';

const bus = mitt();

export default bus;
<!-- 组件A -->
<template>
  <div>
    <button @click="sendMessage">Send Message</button>
  </div>
</template>

<script>
import bus from './EventBus';

export default {
   
  methods: {
   
    sendMessage() {
   
      bus.emit('custom-event', 'Hello from Component A');
    }
  }
}
</script>

<!-- 组件B -->
<template>
  <div>
    <p>{
   {
    message }}</p>
  </div>
</template>

<script>
import bus from './EventBus';

export default {
   
  data() {
   
    return {
   
      message: ''
    };
  },
  mounted() {
   
    bus.on('custom-event', (message) => {
   
      this.message = message;
    });
  }
}
</script>
  1. Vuex / 状态管理: 使用 Vuex 这样的状态管理库来集中管理应用程序的状态。不同的组件可以通过访问共享的状态来实现通信和共享数据。
// 创建 Vuex 存储
import {
    createStore } from 'vuex';

const store = createStore({
   
  state() {
   
    return {
   
      message: 'Hello from Vuex'
    };
  },
  mutations: {
   
    updateMessage(state, newMessage) {
   
      state.message = newMessage;
    }
  }
});

export default store;
<!-- 子组件 ChildComponent.vue -->
<template>
  <div>
    <p>{
   {
    message }}</p>
    <button @click="updateMessage">Update Message</button>
  </div>
</template>

<script>
import {
    useStore } from 'vuex';

export default {
   
  setup() {
   
    const store = useStore();

    const updateMessage = () => {
   
      store.commit('updateMessage', 'Updated message from child');
    };

    return {
   
      message: store.state.message,
      updateMessage
    };
  }
}
</script>

<!-- 父组件 -->
<template>
  <div>
    <child-component />
  </div>
</template>

<script>
import ChildComponent from './ChildComponent.vue';

export default {
   
  components: {
   
    ChildComponent
  }
}
</script>
  1. Provide / Inject: 使用 provide 和 inject API 来在组件树中提供和注入数据。父组件通过 provide 提供数据,子组件通过 inject 来注入需要的数据。
<!-- 祖先组件 -->
<template>
  <div>
    <child-component />
  </div>
</template>

<script>
import {
    provide } from 'vue';

export default {
   
  setup() {
   
    const message = 'Hello from ancestor';
    provide('message', message);
  }
}
</script>

<!-- 后代组件 -->
<template>
  <div>
    <p>{
   {
    injectedMessage }}</p>
  </div>
</template>

<script>
import {
    inject } from 'vue';

export default {
   
  setup() {
   
    const injectedMessage = inject('message');
    return {
   
      injectedMessage
    };
  }
}
</script>
  1. Ref / Reactive: 使用 Vue 3 的 Composition API 中的 ref 和 reactive 来创建和响应式地共享数据,以便不同组件可以访问和修改这些数据。
<!-- 子组件 -->
<template>
  <div>
    <p>{
   {
    message }}</p>
  </div>
</template>

<script>
export default {
   
  data() {
   
    return {
   
      message: 'Hello from child'
    };
  }
}
</script>

<!-- 父组件 -->
<template>
  <div>
    <child-component ref="childRef" />
    <button @click="getChildMessage">Get Child Message</button>
  </div>
</template>

<script>
import {
    ref } from 'vue';

export default {
   
  components: {
   
    ChildComponent
  },
  setup() {
   
    const childRef = ref(null);

    const getChildMessage = () => {
   
      const message = childRef.value.message;
      console.log(message); // 输出:Hello from child
    };

    return {
   
      childRef,
      getChildMessage
    };
  }
}
</script>
  1. 全局事件 / 订阅发布模式: 使用全局事件或订阅发布模式来实现组件之间的通信。不同组件可以订阅和发布事件,以实现数据的传递和交互。
// 创建一个事件总线
const eventBus = new Vue();

// 组件A
const ComponentA = {
   
  methods: {
   
    updateMessage() {
   
      const newMessage = 'Updated message from Component A';
      eventBus.$emit('messageUpdated', newMessage);
    }
  },
  // 组件A的其他逻辑
};

// 组件B
const ComponentB = {
   
  data() {
   
    return {
   
      message: ''
    };
  },
  mounted() {
   
    eventBus.$on('messageUpdated', (newMessage) => {
   
      this.message = newMessage;
    });
  },
  // 组件B的其他逻辑
};

8.useAttrs: useAttrs是 Vue 3 中提供的一个 Composition API,用于获取组件上未声明为props的属性。

<!-- 组件 -->
<template>
  <div>
    <p>{
   {
    customAttribute }}</p>
  </div>
</template>

<script>
import {
    useAttrs } from 'vue';

export default {
   
  setup() {
   
    const attrs = useAttrs();
    return {
   
      customAttribute: attrs['custom-attribute']
    };
  }
}
</script>

<!-- 使用组件 -->
<template>
  <div>
    <custom-component custom-attribute="Custom Attribute Value" />
  </div>
</template>

<script>
import CustomComponent from './CustomComponent.vue';

export default {
   
  components: {
   
    CustomComponent
  }
}
</script>
  1. Pinia: Pinia 是一个基于 Vue 3 的状态管理库,提供了一种更简洁和类型安全的方式来管理和共享组件之间的状态。需要先下载依赖
npm install pinia
//或者
yarn add pinia
// 创建 Pinia 存储
import {
    createPinia } from 'pinia';

const pinia = createPinia();

export default pinia;
<!-- 组件A -->
<template>
  <div>
    <button @click="updateMessage">Update Message</button>
  </div>
</template>

<script>
import {
    useStore } from 'pinia';

export default {
   
  setup() {
   
    const store = useStore();

    const updateMessage = () => {
   
      store.message = 'Updated message from Component A';
    };

    return {
   
      updateMessage
    };
  }
}
</script>

<!-- 组件B -->
<template>
  <div>
    <p>{
   {
    message }}</p>
  </div>
</template>

<script>
import {
    useStore } from 'pinia';

export default {
   
  setup() {
   
    const store = useStore();

    return {
   
      message: store.message
    };
  }
}
</script>
  1. 插槽(Slots): 插槽是一种允许父组件向子组件传递内容的机制。父组件可以在子组件中定义插槽,并将内容传递给插槽,子组件可以根据需要使用这些内容。
<!-- 父组件 -->
<template>
  <div>
    <child-component>
      <!-- 插槽内容 -->
      <template v-slot:content>
        <p>{
   {
    message }}</p>
        <button @click="updateMessage">Update Message</button>
      </template>
    </child-component>
  </div>
</template>

<script>
import ChildComponent from './ChildComponent.vue';

export default {
   
  components: {
   
    ChildComponent
  },
  data() {
   
    return {
   
      message: 'Hello from parent'
    };
  },
  methods: {
   
    updateMessage() {
   
      this.message = 'Updated message from parent';
    }
  }
}
</script>
<!-- 子组件 -->
<template>
  <div>
    <!-- 插槽 -->
    <slot name="content"></slot>
  </div>
</template>

<script>
export default {
   
  // 子组件逻辑
}
</script>
  1. v-model: v-model 是一种用于在父组件和子组件之间实现双向绑定的语法糖。它将value属性和input事件绑定在一起,使得父组件可以通过v-model来直接更新子组件的数据。
<!-- 子组件 -->
<template>
  <div>
    <input :value="value" @input="$emit('update:value', $event.target.value)" />
  </div>
</template>

<script>
export default {
   
  props: ['value']
}
</script>

<!-- 父组件 -->
<template>
  <div>
    <child-component v-model="message" />
    <p>Message: {
   {
    message }}</p>
  </div>
</template>

<script>
import ChildComponent from './ChildComponent.vue';

export default {
   
  components: {
   
    ChildComponent
  },
  data() {
   
    return {
   
      message: ''
    };
  }
}
</script>

这些通信方式可以根据应用程序的需求和复杂性进行选择和组合使用,以实现组件之间的有效通信和协作。

目录
相关文章
|
21天前
|
JavaScript
vue使用iconfont图标
vue使用iconfont图标
111 1
|
2月前
|
缓存 JavaScript UED
Vue3中v-model在处理自定义组件双向数据绑定时有哪些注意事项?
在使用`v-model`处理自定义组件双向数据绑定时,要仔细考虑各种因素,确保数据的准确传递和更新,同时提供良好的用户体验和代码可维护性。通过合理的设计和注意事项的遵循,能够更好地发挥`v-model`的优势,实现高效的双向数据绑定效果。
164 64
|
1天前
|
存储 设计模式 JavaScript
Vue 组件化开发:构建高质量应用的核心
本文深入探讨了 Vue.js 组件化开发的核心概念与最佳实践。
10 1
|
1月前
|
JavaScript 关系型数据库 MySQL
基于VUE的校园二手交易平台系统设计与实现毕业设计论文模板
基于Vue的校园二手交易平台是一款专为校园用户设计的在线交易系统,提供简洁高效、安全可靠的二手商品买卖环境。平台利用Vue框架的响应式数据绑定和组件化特性,实现用户友好的界面,方便商品浏览、发布与管理。该系统采用Node.js、MySQL及B/S架构,确保稳定性和多功能模块设计,涵盖管理员和用户功能模块,促进物品循环使用,降低开销,提升环保意识,助力绿色校园文化建设。
|
2月前
|
前端开发 JavaScript 测试技术
Vue3中v-model在处理自定义组件双向数据绑定时,如何避免循环引用?
Web 组件化是一种有效的开发方法,可以提高项目的质量、效率和可维护性。在实际项目中,要结合项目的具体情况,合理应用 Web 组件化的理念和技术,实现项目的成功实施和交付。通过不断地探索和实践,将 Web 组件化的优势充分发挥出来,为前端开发领域的发展做出贡献。
57 8
|
2月前
|
JavaScript
在 Vue 3 中,如何使用 v-model 来处理自定义组件的双向数据绑定?
需要注意的是,在实际开发中,根据具体的业务需求和组件设计,可能需要对上述步骤进行适当的调整和优化,以确保双向数据绑定的正确性和稳定性。同时,深入理解 Vue 3 的响应式机制和组件通信原理,将有助于更好地运用 `v-model` 实现自定义组件的双向数据绑定。
|
2月前
|
JavaScript 前端开发 开发者
vue学习第一章
欢迎来到我的博客!我是瑞雨溪,一名热爱前端的大一学生,专注于JavaScript与Vue,正向全栈进发。博客分享Vue学习心得、命令式与声明式编程对比、列表展示及计数器案例等。关注我,持续更新中!🎉🎉🎉
57 1
vue学习第一章
|
2月前
|
JavaScript 前端开发 索引
vue学习第三章
欢迎来到瑞雨溪的博客,一名热爱JavaScript与Vue的大一学生。本文介绍了Vue中的v-bind指令,包括基本使用、动态绑定class及style等,希望能为你的前端学习之路提供帮助。持续关注,更多精彩内容即将呈现!🎉🎉🎉
53 1
|
2月前
|
缓存 JavaScript 前端开发
vue学习第四章
欢迎来到我的博客!我是瑞雨溪,一名热爱JavaScript与Vue的大一学生。本文介绍了Vue中计算属性的基本与复杂使用、setter/getter、与methods的对比及与侦听器的总结。如果你觉得有用,请关注我,将持续更新更多优质内容!🎉🎉🎉
47 1
vue学习第四章
|
2月前
|
JavaScript 前端开发 算法
vue学习第7章(循环)
欢迎来到瑞雨溪的博客,一名热爱JavaScript和Vue的大一学生。本文介绍了Vue中的v-for指令,包括遍历数组和对象、使用key以及数组的响应式方法等内容,并附有综合练习实例。关注我,将持续更新更多优质文章!🎉🎉🎉
41 1
vue学习第7章(循环)