Vue组件间的通信方式究竟有哪些

组件间通信的概念

在介绍方法之前,我们先来了解下什么是组件间通信。

我们都知道,组件是Vue的核心功能之一。每个Vue中的.Vue 文件都可以把它看做一个组件。

通信是指发送者通过某种媒体、某种格式将传递信息传递给收集者来达到某种目的。

从广义上来说,任何信息的交通都是组件间通信,即组件(.Vue)通过某种方式来传递信息以达到某个目的。来看个例子,我们在使用UI框架中的table组件,可能会往这个组件中传入一些数据,这就形成了组件间的通信。

通信种类

组件间的通信可以分成四个类型:

  • 父子组件间的通信。
  • 兄弟组件间的通信。
  • 祖孙和后代组件间的通信。
  • 非关系组件间的通信。

组件间通信的方案

1.props

props只能从父组件传递给子组件,也就是所谓的单向传递。通过在子组件设置props属性,来定义从父组件那接收的参数。而且父组件可以通过子组件标签来传递值。

 

Father

体验AI代码助手

代码解读

复制代码

<Children name="jack" age=18 />

 

Children

体验AI代码助手

代码解读

复制代码

props:{ // 字符串形式 name:String // 接收的类型参数 // 对象形式 age:{ type:Number, // 接收的类型为数值 defaule:18, // 默认值为18 require:true // age属性必须传递 } }

2.$emit

$emit是子组件向父组件传递数据的方法。

$emit之所以可以让子组件向父组件传递参数,是因为父组件在子组件中利用v-on来监听函数并接收参数。

子组件通过$emit触发自定义事件,$emit的第二个参数是传递的数值。

 

Father

体验AI代码助手

代码解读

复制代码

<Children @add="cartAdd($event)" />

 

Children

体验AI代码助手

代码解读

复制代码

this.$emit('add', good)

3.ref

ref想必都很熟悉,父组件可以通过设置子组件ref来获取数据。如果在普通的DOM元素上使用,则指向DOM元素;在子组件上使用则指向组件实例,可以通过实例来直接调用组件的方法或访问数据。

 

Father

体验AI代码助手

代码解读

复制代码

<Children ref="foo" /> this.$refs.foo // 获取子组件实例,通过子组件实例我们就能拿到对应的数据

4.EventBus

EventBus用于兄弟组件之间传值,首先要创建一个中央事件总线,兄弟组件则是通过$emit触发自定义事件,另一个兄弟组件是通过$on来监听自定义事件。

 

js

体验AI代码助手

代码解读

复制代码

// 创建一个中央时间总线类 class Bus { constructor() { this.callbacks = {}; // 存放事件的名字 } $on(name, fn) { this.callbacks[name] = this.callbacks[name] || []; this.callbacks[name].push(fn); } $emit(name, args) { if (this.callbacks[name]) { this.callbacks[name].forEach((cb) => cb(args)); } } } // main.js Vue.prototype.$bus = new Bus() // 将$bus挂载到vue实例的原型上 // 另一种方式 Vue.prototype.$bus = new Vue() // Vue已经实现了Bus的功能

 

Children1

体验AI代码助手

代码解读

复制代码

this.$bus.$emit('foo')

 

Children2

体验AI代码助手

代码解读

复制代码

this.$bus.$on('foo', this.handle)

5.parent或$root

通过共同的祖先$parent$root搭建通信桥连。

 

Children1

体验AI代码助手

代码解读

复制代码

this.$parent.on('add',this.add)

 

Children2

体验AI代码助手

代码解读

复制代码

this.$parent.emit('add')

6.attrs和$listeners

$attrs$listeners是Vue中的两个属性,$attrs包含父作用域中传递给子组件的所有属性(除了classstyle和被声明为props的属性)。

它是一个对象,包含剩下所有的HTML特性和事件监听器。而且还可以通过v-bind=$attrs传入内部组件。

 

js

体验AI代码助手

代码解读

复制代码

// child:并未在props中声明foo <p>{{$attrs.foo}}</p> // parent <HelloWorld foo="foo"/>

 

js

体验AI代码助手

代码解读

复制代码

// 给Grandson隔代传值,communication/index.vue <Child2 msg="lalala" @some-event="onSomeEvent"></Child2> // Child2做展开 <Grandson v-bind="$attrs" v-on="$listeners"></Grandson> // Grandson使⽤ <div @click="$emit('some-event', 'msg from grandson')"> {{msg}} </div>

7.provide和inject

provideinject是Vue中在组件中进行依赖注入的两个选项它们允许祖先组件向子孙组件传递数据或资源。这个方法尤其是在嵌套层级较深时特别适合,如果使用props$emit会难以维护。

现在祖先组件定义provide属性,返回传递的值;再到子孙组件通过inject接受组件传递过来的值。

 

Father

体验AI代码助手

代码解读

复制代码

provide(){ return { foo:'foo' }

 

Children

体验AI代码助手

代码解读

复制代码

inject:['foo']

8.vuex

vuex是Vue自身的状态管理模式和库。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方法发生变化。

重要概念

  1. State(状态):存储应用层的状态,任何状态更新都应该遵循Vuex的规定流程。
  2. Getter:类似于Vue中的计算属性,可以从State中派生出一些状态;可以接受state作为第一个参数,也可以接受其他getters作为第二个参数。
  3. Mutation:想要更改store状态的唯一方法是提交mutation。每个mutation都带有一个type(事件类型)和handler(回调函数)。

注意:Mutation必须是同步函数。

  1. Action:与Mutation相似但略有不同,Action提交的是Mutation而不是直接改变状态,而且Action可以包含任意的异步操作。Action要通过satore.dispatch来触发。
  2. Module:Vuex允许我们将store切割成模块(Module)。每个模块都拥有自己的state、mutation、action、getter和嵌套子模块——自上而下进行同样方式的分割。

总结

  • 父子关系的组件数据传递选择 props  与 $emit进行传递,也可选择ref
  • 兄弟关系的组件数据传递可选择$bus,其次可以选择$parent进行传递。
  • 祖先与后代组件数据传递可选择attrslisteners或者 Provide与 Inject
  • 复杂关系的组件数据传递可以通过vuex存放共享的变量。

原文:https://juejin.cn/post/7486668229046403111

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值