Vue的组件间通信
文章目录
在 vue 的组件化开发的过程中,数据交互是其中很重要的环节,不同的组件间如何进行通信就是今天要探讨的话题。所谓的通信就是组件之间获取属性和调用方法的过程。 通常组件之间的关系大致可以分为: 父子组件、多级嵌套组件(也可以叫爷孙组件)、兄弟组件三大类。 本文中的 vue3 的写法都是使用的组合式 api 的写法。
父子组件通信
对于父子组件通信,是最基础也是最常见的组间模式,一般常用的有三种方式:
- props/emit
- $parent/$children/$refs
- $attrs/$listeners
props/emit
vue2/vue3 都是通用的方式,基本的原理就是:
- 父组件通过 v-bind:prop=‘xxx’的方式,传递给子组件,子组件通过定义好的 props 属性接受
- 子组件不能修改 props 的值,数据流是单向的,只能是父 -> 子
- 子组件通过$emit 方式抛出方法,父组件 v-on 监听对应的方法,对数据做处理。
对于 vue3 来说,使用 的组合式 API 新方式是:
|
|
$parent/$children/$refs
- 对于 vue2 来说:
- 子组件获取父组件使用$parent,父组件获取子组件可以使用$children
- 同时还提供组件的引用,在子组件上加上 ref 属性,父组件便可在 mounted 生命周期中使用$refs 获取刚刚设定的那个组件,进而进行通信。
- 对于 vue3 来说:
- 移除了$children,建议使用$refs 来获取子组件
- 不建议使用$parent,需要通过
getCurrentInstance
,进而去找到 parent - 同时使用 的组合式 API 的内容都是私有的,需要通过 defineExpose()方法暴露出去
- $refs 的使用注意定义的变量要和组件上设置的 ref 属性值一样
|
|
$attrs/$listeners
这两者是单向的,只能父 -> 子
- 对于 vue2 来说:
- 子组件通过当前实例上的$attrs属性获取父组件中未被props消费的属性,也就this.$attrs
- 子组件通过当前实例上的$listeners属性获取父组件中未被$emit 消费的方法,也就是 this.$listeners
- 多层嵌套时可以直接通过 v-bind="$attrs"进行透传
- 对于 vue3 来说:
- 移除了$listeners,都通过$attrs 来获取未被子组件消费的属性和方法。
- 多层嵌套时可以直接通过 v-bind="$attrs"进行透传
|
|
多级嵌套组件
- 使用 $attrs/$listeners 做透传即可,单向数据流
- 自定义事件,注意多个监听函数的监听和销毁
- 使用 provide/inject,这是最推荐的方式。
自定义事件
- 对于 vue2 来说:
- 通过全局的 new Vue()作为 eventBus
- 子组件利用$emit()
- 父组件利用$on(), beforeDestroy 中$off()销毁
- 对于 vue3 来说:
- 需要借助第三方的 event-emitter 库
- 子组件 emit()
- 父组件 on(), onBeforeUnmount()中 off 销毁
provide/inject
就是依赖注入的方式,父组件 provide 值,子组件 inject 值
|
|
兄弟组件
一般来说有两种方式:
- 使用全局自定义事件
- 使用 vuex