Vue组件通信-下篇

2022-12-03 11:44:17 浏览数 (2)

前言

接上篇Vue组件通信-上篇文章介绍了Vue组件基本通信方式,主要解决父子组件通信。本篇文章重点介绍兄弟组件、跨级组件是如何通信的。

EventBus

EventBus也称为事件总线。在 Vue 中,EventBus可以作为通信桥梁的概念,就像所有组件共享同一个事件中心一样,可以注册向中心发送或接收事件,因此组件可以并行通知其他组件,但是太不方便了,所以如果使用不慎,就会造成难以维护的“灾难”。因此,需要一个更完整的Vuex作为状态管理中心,将通知的概念提升到共享状态级别。

创建eventBus:

首先,需要创建一个事件总线并将其导出,以便其他模块可以使用或收听它。创建eventBus.js文件,并且导入vue并且创建EventBus实例。

父组件:

这里有additionNum 和 showNum,这两个组件是兄弟组件, 在之前讲解的组件通信方式中兄弟组件是无法通信的,下面介绍怎么使用eventBus通信。

发送事件:

在additionNum.vue中导入event-bus.js,点击button按钮触发additionHandle方法,使用 EventBus.$emit发送addition事件并且携带自增num。

接收事件:

在shownNum.vue中也导入event-bus.js,在mounted中使用EventBus.$on接收addition事件并和参数num。

展示效果:

在additionNum.vue组件中点击button,showNum.vue组件文案变化。

Vuex

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

Vuex解决了多个视图依赖于同一状态和来自不同视图的行为需要变更同一状态的问题,将开发者的精力聚焦于数据的更新而不是数据在组件之间的传递上。

Vuex各个模块的用途:

  • state:用于数据的存储,是 store 中的唯一数据源。
  • getters:如 vue 中的计算属性一样,基于 state 数据的二次包装,常用于数据的筛选和多个数据的相关性计算。
  • mutations:类似函数,改变 state 数据的唯一途径,且不能用于处理异步事件。
  • actions:类似于 mutation,用于提交 mutation。来改变状态,而不直接变更状态,可以包含任意异步操作。
  • modules:类似于命名空间,用于项目中将各个模块的状态分开定义和操作,便于维护。

我使用vue2.x版本,如果安装vuex@4.x版本会有一些问题,该环境安装流程应为:

代码语言:javascript复制
npm install vuex@3.6.5 --save

在src下新建文件夹store,并在文件夹中新建文件index.js,如下:

打开页面后会报异常:[Vue warn]: Error in render: "TypeError: Cannot read properties of undefined (reading 'state')"

出现这个bug的原因是没在main.js中引入store.js并挂载在vue实例上。

解决方法如下图,把store挂到vue实例上。

展示效果:

在A组件上,点击“点击让子组件B接收数据”button,并且使用this.$store.commit给B组件提交方法receiveAMsg方法和参数AMsg。

在B组件上,通过computed方法计算AMessage并且返回this.$store.state.AMsg。

localStorage / sessionStorage

LocalStorage和SessionStorage是客户端浏览器中存在的两个对象,在js中操作它们,存取数据,在必要的时候删除存入的数据。

localStorage的使用:

  • localStorage.setItem(key,value) : 向localStorage中存入键值对。
  • localStorage.getItem(key) : 获取key对应的value值,key不存在时,值为null。
  • localStorage.remove(key) : 移除localStorage中对应key的键值对。
  • localStorage.clear() :清除同源下的localStorage对象中的所有键值对。
  • localStorage.length : localStorage中存入键值对的条目数。
  • localStorage.key(index) : 获取key通过index。

父组件代码:

在父组件中localStorage.setItem("test","123")

子组件代码:

在子组件中localStorage.getItem("test"),就可以拿到"test"参数。

在localStorage可以看到test是123。

SessionStorage的使用:

需要注意的的是在刷新页面时,不会被销毁,关闭当前tab页面,sessionStorage被销毁。

  • sessionStorage.setItem(key,value) : 向localStorage中存入键值对。
  • sessionStorage.getItem(key) : 获取key对应的value值,key不存在时,值为null。
  • sessionStorage.remove(key) : 移除localStorage中对应key的键值对。
  • sessionStorage.clear() :清除同源下的localStorage对象中的所有键值对。
  • sessionStorage.length : localStorage中存入键值对的条目数。
  • sessionStorage.key(index) : 获取key通过index。

这种通信比较简单, 缺点是数据和状态比较混乱,不太容易维护。

attrs / listeners

多级组件嵌套需要传递数据时,通常使用的方法是通过vuex。如果仅仅是传递数据,而不做中间处理,使用 vuex 处理,这就有点大材小用了。所以就有了 $attrs / $listeners ,通常配合 inheritAttrs 一起使用。

$attrs : 包含了父作用域中不被认为 (且不预期为) props 的特性绑定 (class 和 style 除外),并且可以通过 v-bind=”$attrs” 传入内部组件。当一个组件没有声明任何 props 时,它包含所有父作用域的绑定 (class 和 style 除外)。

$listeners : 包含了父作用域中的 (不含 .native 修饰符) v-on 事件监听器。它可以通过 v-on=”$listeners” 传入内部组件。它是一个对象,里面包含了作用在这个组件上的所有事件监听器,相当于子组件继承了父组件的事件。

父组件代码:

子组件代码:

使用v-bind给子子组件传递参数值,并且使用v-on给子子组件传递所有事件。

子子组件代码:

this.$emit('updateInfo'),可以触发 father 组件中的updateInfo函数。

接受子组件$attrs渲染组件代码。

结语

本篇文章 上篇文章一共介绍了八种常用的Vue组件通信方法,总结使用方式如下:

  • 父子组件通信: props / emit、parent / children、 provide / inject、ref、attrs / listeners。
  • 兄弟组件通信: EventBus、Vuex。
  • 跨级通信: EventBus、Vuex、provide / inject 、attrs / listeners。

在实际项目中需要按照需求选择合理的组件通信方法,一旦选择了不合理的方式会后续维护极其复杂。

0 人点赞