zl程序教程

您现在的位置是:首页 >  前端

当前栏目

Vue组件通信

2023-09-11 14:15:54 时间

一、兄弟组件

1.1 兄弟组件通过父组件进行通讯

1.2 兄弟组件通过bus进行通讯

业务场景:

搜索组件参数的改变,需要改变图表组件的参数,并触发图表组件的重载

技术分析1:改变图表组件的参数

搜索组件和图表组件属于兄弟组件。但是由于组件嵌套过深,无法通过父组件进行通讯,示意图如下:

这里有两种方式:

① 使用Vue中的bus进行通讯

② 通过Vuex进行通讯

我们挨个进行介绍。

首先是通过bus进行通讯,其实这个原理和父子之间通讯的原理差不多,既然无法直接到达父组件,那么,就通过一个新的vue组件去充当两者之间的父组件。从而实现通讯。

示意图如下:

 原理上如此,但实际上,Root组件本身就可以充当Bus组件。具体做法为,在Bus组件的created钩子函数中将bus指向root组件即可,代码如下:

created() {
    // 兄弟组件之间的总线
    Vue.prototype.$bus = this;
}

然后在搜索组件中,参数改变时,通过emit发出请求,传递参数。

在图标组件中通过on进行接收。代码如下:

// 搜索组件:
clickChange(params){
	// 这里参数传递做简单处理
	this.$bus.$emit('queryChange', params);
}
// 图表组件
created(){
	this.$bus.$on('queryChange', this.paramChange(params));
}

通过vuex的通讯就是按照规则去写就可以了,可参考:Vuex的使用(案例解析)_Don't disturb me!的博客-CSDN博客_vuex使用实例

但是有一个要注意的点是,如果你是按模块写的vuex,并使用了namespaced命名空间,那么在使用getters获得变量,commit改变变量时,记得写模块路径。

举个例子,我们把搜索组件和图表组件需要传递的参数放在了store/modules/component这个路径下,变量的名称是 param。如果我们想要获取param的值,则需要写:

this.store.getters['component/param']

可参考vuex官网namespaced介绍:

Module | Vuex

技术分析2:图表组件的重载

当时解决这个问题的时候,有一个难点存在。即,图表组件本身具有层级结构:

 为了保证扩展性,总线监听的参数param在Base组件中。

因此,在每个单独的组件中,对param的变化进行监听。当监听到param发生变化时,触发reload函数。并通过计算属性将param参数传到对应请求参数中。

    // 当param变化的时候,图表组件进行响应
    @Watch('param', { deep: true })
    queryChange() {
      this.reload();
    }
​
   // 需要合并来自兄弟组件(搜索组件)的param
    get dateQuery() {
      return this.param;
    }

二、父子组件

子组件即时响应父组件属性变化

父组件可以通过prop向子组件传递信息,但是当prop改变的时候,子组件监听不到。原因是,通过prop传过来的属性,在mounted阶段被挂载之后,就监听不到了。

这个时候,可以使用计算属性,直接返回prop,也可以使用watch监听prop