当前位置: 首页 > article >正文

vue2和vue3中的组件间通信知识点总结

vue2中组件间通信

在Vue2中,组件间的通信是构建复杂应用的关键。以下是一些常见的Vue2组件间通信方式,并附有详细说明和示例:

1. Props(父子组件通信)

Props是Vue中用于父子组件通信的一种机制。父组件通过属性(Props)将数据传递给子组件。

Vue2中的组件间通信方式多种多样,选择哪种方式取决于具体的应用场景和需求。在实际开发中,应根据组件间的关系和通信的复杂度来选择最合适的通信方式。

这种方式通常用于祖先组件向子孙组件传递数据或事件监听器

  • 示例
    <!-- 父组件 -->  
    <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>  
      
    <!-- 子组件 -->  
    <template>  
      <div>  
        <p>{{ message }}</p>  
      </div>  
    </template>  
      
    <script>  
    export default {  
      props: ['message']  
    };  
    </script>

    2. $emit(子父组件通信)

    子组件通过$emit触发自定义事件,父组件监听并响应这些事件,从而实现子父组件间的通信。

  • 示例
    <!-- 子组件 -->  
    <template>  
      <button @click="sendMessage">Send Message to Parent</button>  
    </template>  
      
    <script>  
    export default {  
      methods: {  
        sendMessage() {  
          this.$emit('custom-event', 'Hello from Child');  
        }  
      }  
    };  
    </script>  
      
    <!-- 父组件 -->  
    <template>  
      <div>  
        <child-component @custom-event="handleCustomEvent"></child-component>  
      </div>  
    </template>  
      
    <script>  
    import ChildComponent from './ChildComponent.vue';  
      
    export default {  
      components: {  
        ChildComponent  
      },  
      methods: {  
        handleCustomEvent(message) {  
          console.log('Received message from child:', message);  
        }  
      }  
    };  
    </script>

    3. EventBus(兄弟组件通信)

    通过创建一个中央事件总线EventBus,兄弟组件可以通过emit触发自定义事件,并通过on监听这些事件,从而实现兄弟组件间的通信。

  • EventBus文件
    // EventBus.js  
    import Vue from 'vue';  
    export const EventBus = new Vue();
  • 兄弟组件1
    <template>  
      <button @click="sendMessage">Send Message to Brother</button>  
    </template>  
      
    <script>  
    import { EventBus } from './EventBus.js';  
      
    export default {  
      methods: {  
        sendMessage() {  
          EventBus.$emit('custom-event', 'Hello from Brother1');  
        }  
      }  
    };  
    </script>
  • 兄弟组件2
    <template>  
      <p>{{ message }}</p>  
    </template>  
      
    <script>  
    import { EventBus } from './EventBus.js';  
      
    export default {  
      data() {  
        return {  
          message: ''  
        };  
      },  
      created() {  
        EventBus.$on('custom-event', (message) => {  
          this.message = message;  
        });  
      }  
    };  
    </script>

    4. Vuex(全局状态管理)

    Vuex是一个专为Vue.js应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。使用Vuex可以实现任意组件之间的通信。

  • 安装Vuex
    npm install vuex --save
  • 创建Store文件
    // store/index.js  
    import Vue from 'vue';  
    import Vuex from 'vuex';  
      
    Vue.use(Vuex);  
      
    export default new Vuex.Store({  
      state: {  
        globalMessage: ''  
      },  
      mutations: {  
        setGlobalMessage(state, message) {  
          state.globalMessage = message;  
        }  
      }  
    });
  • 使用Vuex的组件
    <!-- 组件1 -->  
    <template>  
      <button @click="sendMessage">Send Message to Anywhere</button>  
    </template>  
      
    <script>  
    export default {  
      methods: {  
        sendMessage() {  
          this.$store.commit('setGlobalMessage', 'Hello from Vuex');  
        }  
      }  
    };  
    </script>  
      
    <!-- 组件2 -->  
    <template>  
      <p>{{ globalMessage }}</p>  
    </template>  
      
    <script>  
    export default {  
      computed: {  
        globalMessage() {  
          return this.$store.state.globalMessage;  
        }  
      }  
    };  
    </script>

    5. Provide/Inject(祖先与后代组件通信)

    Provide/Inject是Vue2.2.0+新增的API,用于祖先组件向其所有后代组件提供数据/方法,后代组件通过inject选项来接收。

  • 祖先组件
    <template>  
      <div>  
        <descendant-component></descendant-component>  
      </div>  
    </template>  
      
    <script>  
    import { provide } from 'vue';  
    import { globalMessage } from './symbols.js';  
      
    export default {  
      setup() {  
        provide(globalMessage, 'Hello from Ancestor');  
      }  
    };  
    </script>
  • 后代组件
    <template>  
      <div>  
        <p>{{ foo }}</p>  
      </div>  
    </template>  
      
    <script>  
    export default {  
      inject: ['foo']  
    };  
    </script>

    6. $refs

    refs是一个对象,持有注册过ref特性的所有DOM元素和组件实例。父组件可以通过refs主动获取子组件的实例,从而直接调用子组件的方法或访问子组件的数据。

    <!-- 父组件 -->  
    <template>  
      <div>  
        <child-component ref="child"></child-component>  
      </div>  
    </template>  
      
    <script>  
    import ChildComponent from './ChildComponent.vue';  
      
    export default {  
      components: {  
        ChildComponent  
      },  
      mounted() {  
        const child = this.$refs.child;  
        console.log(child.str); // 获取子组件的数据  
        child.fn('调用了子组件的方法'); // 调用子组件的方法  
      }  
    };  
    </script>  
      
    <!-- 子组件 -->  
    <template>  
      <input type="text" />  
    </template>  
      
    <script>  
    export default {  
      data() {  
        return {  
          str: '我是数据'  
        };  
      },  
      methods: {  
        fn(e) {  
          console.log(e);  
        }  
      }  
    };  
    </script>

    7. parent或root

    通过parent或root,组件可以访问其父组件或根组件的实例,从而进行通信。但这种方式通常不推荐使用,因为它破坏了组件的封装性,使组件间的依赖关系变得复杂。

    8. attrs与listeners

  • **attrs∗∗:包含了父级作用域中不作为prop被识别(且获取)的特性绑定(class和style除外)。当组件没有声明某个prop时,这个prop会作为一个特性(attribute)绑定到组件的根元素上,并可以通过attrs进行访问。
  • **listeners∗∗:包含了父级作用域中的v−on事件监听器。这些监听器可以在组件内部通过listeners进行访问,并可以绑定到组件内部的元素上。

vue3中组件间通信

在Vue3中,组件间的通信方式多种多样,以下是几种常见的通信方式及示例:

一、props(父组件向子组件传递数据)

  • 说明:父组件通过props属性将数据传递给子组件。在子组件中,可以使用defineProps来接收这些数据。
  • 示例
    <!-- 父组件 -->  
    <template>  
      <div>  
        <h1>我是父组件</h1>  
        <child :name="name" age="12"></child>  
      </div>  
    </template>  
      
    <script setup lang="ts">  
    import child from './child.vue'  
    import { ref } from 'vue'  
    const name = ref('父亲名字')  
    </script>  
      
    <!-- 子组件 -->  
    <template>  
      <div>  
        <h1>我是子组件</h1>  
        <p>我收到了父组件的数据: {{ name }}</p>  
        <p>{{ props.age }}</p>  
      </div>  
    </template>  
      
    <script setup lang="ts">  
    const props = defineProps(["name", "age"]);  
    </script>

    二、自定义事件(子组件向父组件发送消息)

  • 说明:子组件通过$emit触发自定义事件,并传递数据给父组件。父组件通过监听这些事件来接收数据。
  • 示例
    <!-- 父组件 -->  
    <template>  
      <div>  
        <h1>我是父组件</h1>  
        <child @mimi="tingmimi"></child>  
        <p>我听到了子组件的秘密: {{ msg }}</p>  
      </div>  
    </template>  
      
    <script setup lang="ts">  
    import child from './child.vue'  
    import { ref } from 'vue'  
    let msg = ref('还没听到秘密')  
    const tingmimi = function(message: any) {  
      msg.value = message  
    }  
    </script>  
      
    <!-- 子组件 -->  
    <template>  
      <div>  
        <h1>我是子组件</h1>  
        <button @click="saymimi">点我给父组件说我的秘密</button>  
      </div>  
    </template>  
      
    <script setup lang="ts">  
    let $emit = defineEmits(['mimi'])  
    const saymimi = function() {  
      $emit('mimi', '是邓紫棋的我的秘密啦')  
    }  
    </script>

    三、mitt全局事件总线(兄弟组件间通信)

  • 说明:使用mitt库创建一个全局事件总线,允许任意组件间进行通信。
  • 示例
    # 安装mitt  
    npm i mitt
    // 在utils文件创建mitt.ts文件  
    import mitt from 'mitt'  
    const $bus = mitt()  
    export default $bus
    <!-- 子组件1 -->  
    <template>  
      <div>  
        <h1>我是子组件1</h1>  
        <p>我收到了来自兄弟的信息: {{ message }}</p>  
      </div>  
    </template>  
      
    <script setup lang="ts">  
    import $bus from '../utils/mitt'  
    import { ref } from 'vue'  
    let message = ref('还不知道呢')  
    $bus.on('mimi', (msg: any) => {  
      message.value = msg  
    })  
    </script>  
      
    <!-- 子组件2 -->  
    <template>  
      <div>  
        <h1>我是子组件2</h1>  
        <button @click="sayborder">点我给兄弟发秘密</button>  
      </div>  
    </template>  
      
    <script setup lang="ts">  
    import $bus from '../utils/mitt'  
    const sayborder = function() {  
      $bus.emit('mimi', { mimi: "遗产全都给我了" })  
    }  
    </script>

    四、v-model(父子组件数据双向绑定)

  • 说明v-model可以用于父子组件间的数据双向绑定。在子组件中,需要定义propsemits来配合v-model的使用。
  • 示例
    <!-- 父组件 -->  
    <template>  
      <div>  
        <h1>我是父组件</h1>  
        <p>我的财产: {{ money1 }}</p>  
        <child v-model:money="money1"></child>  
      </div>  
    </template>  
      
    <script setup lang="ts">  
    import { ref } from 'vue'  
    import child from './child.vue'  
    let money1 = ref(122000)  
    </script>  
      
    <!-- 子组件 -->  
    <template>  
      <div>  
        <h1>我是子组件</h1>  
        <input type="text" v-model="value.money">  
        <p>父亲的钱: {{ money }}</p>  
        <button @click="sayborder()">点我偷掉父亲的钱</button>  
      </div>  
    </template>  
      
    <script setup lang="ts">  
    const value = defineProps(['money'])  
    const $emit = defineEmits(['update:money'])  
    const sayborder = function() {  
      $emit('update:money', value.money - 200)  
    }  
    </script>

    五、useAttrs(获取组件的属性)

  • 说明useAttrs可以用于获取组件上未被props声明的属性。
  • 示例
    <!-- 父组件 -->  
    <template>  
      <div>  
        <h1>我是父组件</h1>  
        <child :money="money" data="extraData"></child>  
      </div>  
    </template>  
      
    <script setup lang="ts">  
    import { ref } from 'vue'  
    import child from './child.vue'  
    const money = ref(122000)  
    </script>  
      
    <!-- 子组件 -->  
    <template>  
      <div>  
        <h1>我是子组件</h1>  
        <p>收到了父亲的财产: {{ money }}</p>  
        <p>额外数据: {{ extraData }}</p>  
      </div>  
    </template>  
      
    <script setup lang="ts">  
    import { useAttrs } from 'vue'  
    let attrs = useAttrs()  
    let { money, data: extraData } = attrs  
    </script>

    六、ref与$parent(父组件访问子组件实例,子组件访问父组件实例)

  • 说明:使用ref可以在父组件中获取子组件的实例,从而直接调用子组件的方法或访问其数据。同时,子组件可以通过$parent访问父组件的实例。
  • 示例(仅展示父组件访问子组件):
    <!-- 父组件 -->  
    <template>  
      <div>  
        <h1>我是父组件</h1>  
        <child ref="mychildref"></child>  
        <button @click="accessChild">访问子组件</button>  
      </div>  
    </template>  
      
    <script setup lang="ts">  
    import child from "./child.vue"  
    import { ref } from "vue"  
    const mychildref = ref(null)  
    const accessChild = () => {  
      console.log(mychildref.value.someChildMethod()) // 假设子组件有一个someChildMethod方法  
    }  
    </script>  
      
    <!-- 子组件 -->  
    <template>  
      <div>  
        <h1>我是子组件</h1>  
      </div>  
    </template>  
      
    <script setup lang="ts">  
    const someChildMethod = () => {  
      return "我是子组件的方法"  
    }  
    defineExpose({  
      someChildMethod // 对外暴露方法,以便父组件访问  
    })  
    </script>

    七、Provide/Inject(跨层级组件通信)

  • 说明Provide/Inject是Vue3中新增的一种组件通信方式,用于实现跨层级的组件通信。祖先组件通过provide提供数据,后代组件通过inject获取数据。
  • 示例
    <!-- 祖先组件 -->  
    <template>  
      <div>  
        <h1>我是祖先组件</h1>  
        <parent></parent>  
      </div>  
    </template>  
      
    <script setup lang="ts">  
    import { provide } from 'vue'  
    import parent from './parent.vue'  
    provide('sharedData', '这是共享的数据')  
    </script>  
      
    <!-- 父组件 -->  
    <template>  
      <div>  
        <h1>我是父组件</h1>  
        <child></child>  
      </div>  
    </template>  
      
    <script setup lang="ts">  
    import child from './child.vue'  
    </script>  
      
    <!-- 子组件 -->  
    <template>  
      <div>  
        <h1>我是子组件


http://www.kler.cn/news/337099.html

相关文章:

  • Redis: Sentinel工作原理和故障迁移流程
  • 【Spring】“请求“ 之后端传参重命名,传递数组、集合,@PathVariable,@RequestPart
  • python全栈学习记录(二十三)反射、内置方法、类相关的函数、元类
  • 性能测试学习6:jmeter安装与基本配置/元件/线程组介绍
  • 智能涌现|迎接智能时代,算力产业重构未来
  • java 读取导出 resources目录下的文件,导出给前端
  • IDEA 最新版创建 Sping Boot 项目没有 JDK8 选项的解决方案
  • 运维工具箱
  • 高级java每日一道面试题-2024年10月2日-分布式篇-什么是FLP 不可能性定理?
  • 鸿蒙next开发第一课03.ArkTs语法介绍-案例
  • 操作系统 | 学习笔记 | 王道 | 4.2 目录
  • 使用 Spring Boot 在电商平台中动态调整促销信息
  • Java学习——JDK
  • vue3 antd-design-vue3 日期组件语言不显示中文问题
  • 【数据结构与算法】B树
  • 论文翻译 | ReWOO: 高效增强语言模型的解耦推理
  • Linux搭建Hadoop集群(详细步骤)
  • 构建带有调试符号的srsRAN 4G
  • 十三、MySQL高级—读写分离(6)
  • Leetcode——数组:移除元素—27.移除元素