_^_^_nicole

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

统计

vue中组件间通信方式的总结

面试中,经常会问到vue中组件间的通信方式有哪些?

今天我们就来总结下。

 

 

vue中组件间的通信方式

 

 

方法一、props/$emit

这是我们比较熟悉的方式,主要是父子组件之间的传递方式,父传子使用props,子传父使用$emit.

此方法经常使用,就不罗列代码了

 

 

方法二、$emit/$on

这种方法通过一个空的Vue实例作为中央事件总线EventBus(事件中心),用它来触发事件和监听事件,巧妙而轻量地实现了任何组件间的通信,包括父子、兄弟、跨级。当我们的项目比较大时,可以选择更好的状态管理解决方案vuex。

 

用法如下:

第一步:项目中创建一个js文件(我通常给它取个名字为bus.js),引入vue,创建一个vue实例,导出这个实例,代码如下(一共就两行):

 

 

 

import Vue from 'Vue'export default new Vue

 

 

第二步:在两个需要通信的两个组件中分别引入这个bus.js

 

 

 

import Bus from '这里是你引入bus.js的路径' // Bus可自由更换喜欢的名字

 

 

第三步:传递数据的组件里通过vue实例方法$emit发送事件名称和需要传递的数据。(发送数据组件)

 

 

Bus.$emit('click',data) // 这个click是一个自定义的事件名称,data就是你要传递的数据

 

 

第四步:被传递数据的组件内通过vue实例方法$on监听到事件和接受到数据。(接收数据的组件)这里通常挂载监听在vue生命周期created和mounted当中的一个,具体使用场景需要具体的分析,这里不说这个。

 

 

 

 

Bus.$on('click',target => {  console.log(target)    // 注意:发送和监听的事件名称必须一致,target就是获取的数据,可以不写target。只要你喜欢叫什么都可以(当然了,这一定要符合形参变量的命名规范)})

 

 

通过以上的四步其实就已经实现了最简单的eventbus的实际应用了。

 

但是到这儿后,一定要注意一个最容易忽视,又必然不能忘记的东西,那就是清除事件总线eventBus.不手动清除,它是一直会存在的

 

第五步:在vue生命周期beforeDestroy或者destroyed中用vue实例的$off方法清除eventBus

 

 

 

beforeDestroy(){   bus.$off('click')}

 

 

 

方法三、vuex (自己查阅具体方法) 

 

 

方法四、$attrs/$listeners (自己查阅具体方法) 

多级组件嵌套需要传递数据时,通常使用的方法是通过vuex。但如果仅仅是传递数据,而不做中间处理,使用 vuex 处理,未免有点大材小用。为此Vue2.4 版本提供了另一种方法----$attrs/$listeners

 

$attrs:包含了父作用域中不被 prop 所识别 (且获取) 的特性绑定 (class 和 style 除外)。当一个组件没有声明任何 prop 时,这里会包含所有父作用域的绑定 (class 和 style 除外),并且可以通过 v-bind="$attrs" 传入内部组件。通常配合 interitAttrs 选项一起使用。

 

$listeners:包含了父作用域中的 (不含 .native 修饰器的) v-on 事件监听器。它可以通过 v-on="$listeners" 传入内部组件

 

 

方法五、provide/inject

Vue2.2.0新增API,这对选项需要一起使用,以允许一个祖先组件向其所有子孙后代注入一个依赖,不论组件层次有多深,并在起上下游关系成立的时间里始终生效。一言而蔽之:祖先组件中通过provider来提供变量,然后在子孙组件中通过inject来注入变量。

provide / inject API 主要解决了跨级组件间的通信问题,不过它的使用场景,主要是子组件获取上级组件的状态,跨级组件间建立了一种主动提供与依赖注入的关系。

 

举个例子

假设有两个组件:A.vue 和 B.vue,B 是 A 的子组件

 

复制代码
// A.vue

 

export default {  provide: {    name: '浪里行舟'  }}
 

// B.vue

 

export default {  inject: ['name'],  mounted () {    console.log(this.name);  // 浪里行舟  }}
 
复制代码

 

 

方法六、$parent / $children与 ref

ref:如果在普通的 DOM 元素上使用,引用指向的就是 DOM 元素;如果用在子组件上,引用就指向组件实例

 

$parent / $children:访问父 / 子实例

需要注意的是:这两种都是直接得到组件实例,使用后可以直接调用组件的方法或访问数据。我们先来看个用 ref来访问组件的例子:

 

复制代码
// component-a 子组件

 

export default {  data () {    return {      title: 'Vue.js'    }  },  methods: {    sayHello () {      window.alert('Hello');    }  }}
 

// 父组件

 

<template>  <component-a ref="comA"></component-a></template>
<script>
export default {
mounted () {
const comA = this.$refs.comA;
   console.log(comA.title);
 // Vue.js
    comA.sayHello(); 弹窗
  }}
</script>
复制代码

 

不过,这两种方法的弊端是,无法在跨级或兄弟间通信。

 

 

 

总结

 

常见使用场景可以分为三类:

 

父子通信:

父向子传递数据是通过 props,子向父是通过 events($emit);通过父链 / 子链也可以通信($parent / $children);ref 也可以访问组件实例;provide / inject API;$attrs/$listeners

 

兄弟通信:

Bus;Vuex

 

跨级通信:

Bus;Vuex;provide / inject API、 $attrs/$listeners

 

 



苟有恒 , 何必三更眠五更起关注我,一起学习吧
鼓励一下,赐个赞 和 在看

posted on   _^_^_nicole  阅读(54)  评论(0编辑  收藏  举报

相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
点击右上角即可分享
微信分享提示