组件通信汇总

组件通信汇总_第1张图片

如上图所示, A与B、A与C、B与D、C与E组件之间是父子关系; B与C之间是兄弟关系;A与D、A与E之间是隔代关系; D与E是堂兄关系(非直系亲属)

针对以上关系我们归类为:

父子组件之间通信
非父子组件之间通信(兄弟组件、隔代关系组件等)
因此介绍在不同的场景下如何选择有效方式实现的组件间通信方式,以更好理解组件间的通信。

组件通信的方式有哪些

1、props:用于父=》子组件通信

  • 父组件通过props的方式向子组件传递数据,而子组件通过$emit 可以向父组件通信。
  • 举例:子组件的props选项能够接收来自父组件数据。没错,仅仅只能接收,props是单向绑定的,即只能父组件向子组件传递,不能反向。而传递的方式也分为两种

1、静态传递

子组件通过props选项来声明一个自定义的属性,然后父组件就可以在嵌套标签的时候,通过这个属性往子组件传递数据了。




 


 

2、动态传递

我们已经知道了可以像上面那样给 props 传入一个静态的值,但是我们更多的情况需要动态的数据。这时候就可以用 v-bind 来实现。通过v-bind绑定props的自定义的属性,传递去过的就不是静态的字符串了,它可以是一个表达式、布尔值、对象等等任何类型的值。

 



 


总结: prop 只可以从上一级组件传递到下一级组件(父子组件),即所谓的单向数据流。而且 prop 只读,不可被修改,所有修改都会失效并警告。

2、自定义事件:@on,@emit

可以实现子给父通信即vm.$emit( event, arg )$emit绑定一个自定义事件event,当这个这个语句被执行到的时候,就会将参数arg传递给父组件,父组件通过@event监听并接收参数。

//父组件


//子组件

3、全局事件总线eventBus:$bus 全能

对于比较小型的项目,没有必要引入 vuex 的情况下,可以使用 eventBus。
它的实现思想也很好理解,在要相互通信的两个组件中,都引入同一个新的vue实例,然后在两个组件中通过分别调用这个实例的事件触发和监听来实现通信。

//eventBus.js
import Vue from 'vue';
export default new Vue();


4、pubsub-js

vue当中几乎不用(因为vue中有全局事件总线和这个第三方提供的库功能重复) 但全能

含义:消息订阅与发布
-(由于原生js实现较困难,推荐用第三方库pubsub-js (npm i pubsub-js)

理解:需要消息的人=》订阅消息subscribe,
发布消息的人=》发布消息publish,

实现:需要消息的人:import pubsub from "pubsub-js",并在

mouted(){
this.pubId=pubsub.subscribe('hello‘,function(msgName,data)
      {console.log(‘有人发布了hello消息,hello消息的回调执行了’,msgName,data)
     }
   )
}

发布消息的人:import pubsub from "pubsub-js",在事件函数里

methods:{xxxx事件(){ pubsub.publish(‘hello’,666)}}

效果:有人发布了hello消息,hello消息的回调执行了 hello 666

取消订阅: pubsub.unsubscribe('this.pubId')(即需要指定哪个id的消息被取消订阅)

5、插槽

插槽 

就是子组件中的提供给父组件使用的一个占位符,用 表示,父组件可以在这个占位符中填充任何模板代码,如 HTML、组件等,填充的内容会替换子组件的标签。
1、以最简单插槽为例:在子组件中放一个占位符

//子组件

2、在父组件中给这个占位符填充内容

//父组件

展示效果:
组件通信汇总_第2张图片

  • 但如果没有用插槽,则数据传递不进来,没有多云那一行

 总结:如果子组件没有使用插槽,父组件如果需要往子组件中填充模板或者html, 是没法做到的。

插槽使用 - 具名插槽
描述:具名插槽其实就是给插槽取个名字。一个子组件可以放多个插槽,而且可以放在不同的地方,而父组件填充内容时,可以根据这个名字把内容填充到对应插槽中。代码如下:

1、子组件的代码,设置了两个插槽(header和footer)


 

 


2、父组件填充内容, 父组件通过 v-slot:[name] 的方式指定到对应的插槽中


 

 


组件通信汇总_第3张图片

 6、vuex

https://blog.csdn.net/weixin_51225684/article/details/120347418?spm=1001.2014.3001.5502

 7、$attrs和$listeners

$attrs 以及 $listeners 的出现解决的就是:组件在其中传递 props 以及事件的过程中,不必在写多余的代码,仅仅是将 $attrs 以及 $listeners 向上或者向下传递即可。

inheritAttrs:默认值 true,继承所有的父组件属性(除 props 的特定绑定)作为普通的
HTML特性应用在子组件的根元素上,如果你不希望组件的根元素继承特性设置
inheritAttrs: false ,但是 class 属性会继承(简单的说,inheritAttrs:true 
继承除 props 之外的所有属性;inheritAttrs:false 只继承 class style 属性)
$attrs–继承所有的父组件属性(除了 prop 传递的属性、class 和 style ),
一般用在子组件的子元素上
$listeners属性,它是一个对象,里面包含了作用在这个组件上的所有监听器,你就可以
配合 v-on="$listeners" 将所有的事件监听器指向这个组件的某个特定的子元素。(相当
于子组件继承父组件的事件)

示例

A组件(App.vue)




B组件(Child1.vue)




C 组件 (Child2.vue)




组件通信汇总_第4张图片
 

8、$parent和$children

$parent:子组件访问父组件
$children:父组件访问子组件

$parent  子组件获取父组件的数据、调用父组件的方法

父组件


 


 

子组件


$children   父组件获取子组件的数据、调用子组件的方法

父组件


 


 

子组件


9、provide和inject

provide:是一个对象,或者是一个返回对象的函数。里面呢就包含要给子孙后代的东西,也就是属性和属性值。

inject:一个字符串数组,或者是一个对象。属性值可以是一个对象,包含from和default默认值。

const Child = {
  inject: {
    foo: {
      from: 'bar',
      default: 'foo'
    }
  }
}

 from表示在可用的注入内容中搜索用的 key,default当然就是默认值。

案例:

爷爷组件 


 

 

儿子组件 


 

 

孙组件:


 

 

你可能感兴趣的:(vue.js,前端,javascript)