组件间通信的几种方式

本文总结了Vue组件通信的常见方式,包括props/$emit实现父子通信,$attr/$listener处理祖孙关系,provide/inject进行跨级通信,以及在Vue3中被替代的事件总线,最后提到了状态管理库Vuex的重要性和独立文章计划。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这几天看了tiny-emmity的源码,也了解了vue2中事件总线的具体流程和使用方法,在这里顺便就把vue组件通信的几种方式列举一下,方便日后自己回顾。

一、props / $emit

父组件通过props向子组件传递,子组件向父组件传值:子组件里用emit,父组件用@event监听

父->子 / 子 ->父

/**父组件*/
<template>
  <div id="app">
    <Bcom :message=msg @getBmsg="getbsmg"></Bcom>
  </div>
</template>


<script>
import Bcom from 'views/test/Bcom'
export default {
  components:{Bcom},
  data(){
    return{
      msg:"B组件"
    }
  },
  methods:{
    getbmsg(bmsg){
      console.log(bmsg)
    }
  }
}
</script>



/**子组件*/
<template>
  <h1>{{msg}}</h1>
</template>

<script>
export default {
  props:['msg'],
  mounted() {
    this.$emit('getBmsg','btoa')
  }
}
</script>

二、 $attr / $listener

当两个组件是祖孙的关系时,如果要传递值,用prop可能就是逐个传递。
但vue2.4中新增的 a t t r / attr/ attr/listener,可以直接解决向上或向下传递。

孙辈组件中能触发A中的函数是因为 B组件调用C的时候, 使用v-on绑定了 l i s t e n e r s 通 过 v − b i n d 绑 定 listeners 通过v-bind绑定 listenersvbindattrs, C组件可以直接获取到A组件传递下来的props,但除了B中用过的

A

<template>
  <div id="app">
    <Bcom
      :bmsg="Bmsg"
      :cmsg="Cmsg"
      :BtoA="BtoA"
      :CtoA="CtoA"
    ></Bcom>
  </div>
</template>


<script>
import Bcom from 'views/test/Bcom'
export default {
  components:{Bcom},
  data(){
    return{
      Bmsg:"B组件",
      Cmsg:"B组件",
    }
  },
  methods:{
    BtoA(){
      console.log('b2a')
    },
    CtoA(){
      console.log('c2a')
    },
  }
}
</script>

B

<template>
  <h1>{{bmsg}}</h1>
  <Ccom v-bind="$attrs" v-on="$listeners"></Ccom>
</template>

<script>
import Ccom from './Ccom'
export default {
  props:['bmsg'],
  components:{Ccom},
  mounted() {
    this.$emit('BtoA')
  }
}
</script>

C

<template>
  <h1>{{cmsg}}</h1>
</template>

<script>
export default {
  props:['cmsg'],
  mounted() {
    this.$emit('CtoA')
  }
}
</script>

三、provide/inject

祖先组件中通过provide提供变量, 然后在子孙组件中通过inject注入变量。
provide / inject API 主要解决了跨级组件间的通信问题,不过它的使用场景,主要是子组件获取上级组件的状态,跨级组件间建立了一种主动提供与依赖注入的关系。
这里的举例就以数据响应式形式,即祖先组件的变量值改变,子孙也会跟着一起改变

<template>
  <div id="app">
  </div>
</template>


<script>
export default {
  data(){
    return{
      color:'red'
    }
  },
  // provide (){
  //   return {
  //     theme:{
  //       color:this.color //此方式A组件color值变化,子孙组件不会变化
  //     }
  //   }
  // },

  // provide(){
  //   return {
  //     theme:this //方法一:提供祖先实例
  //   }
  // },

  // 方法二,使用vue2.6最新Api, Vue.observable
  provide(){
    this.theme = Vue.observable({
      color:'blue'
    });
    return{
      theme:this.theme
    }
  }
}
</script>

四、vue事件总线(V3移除)

vue3中移除了事件总线的功能,但提供了两个库 mitt(ts) 或 tiny-emitter(js)来代替。
我将会写一篇关于tiny-emitter的源码解析,总共也只有两百多行,不麻烦。

五、vuex

这部分内容比较重要,今后将单独写一篇文章

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值