Common communication modes of components

  1. props

  2. e m i t / emit/
    on
  3. event
  4. bus
  5. vuex
  6. $refs

In a smaller way

  1. $parent
  2. $children
  3. $root
  4. provide/inject
  5. The characteristics of prop
    • $attrs
    • $listeners

$parent/$root

Sibling components can communicate via common ancestor bypass, parent or parent or parent or root

// brother1 
this.$parent.$on('foo', handle) 
// brother2 
this.$parent.$emit('foo')

Copy the code

$children

The parent component can communicate with the child component through $children.

// parent 
this.$children[0].xx = 'xxx'
Copy the code

Note: $children does not guarantee child order

$listeners “/$listeners

Contains property bindings (except class and style) that are not recognized (and retrieved) as prop in the parent scope. When a component does not declare any prop, all parent-scoped bindings (except class and style) are included, and internal components can be passed in via V-bind =”$attrs” — useful when creating higher-level components.

// child: foo is not declared in props
<p>{{$attrs.foo}}</p>
 
// parent 
<HelloWorld foo="foo"/>
Copy the code
// The parent uses child2 to pass values to Grandson
<Child2 msg="lalala" @some-event="onSomeEvent"></Child2>
 
// Take grandson as child2
<Grandson v-bind="$attrs" v-on="$listeners"></Grandson>
 
// Grandson component used by grandson
<div @click="$emit('some-event', 'msg from grandson')">    {{msg}} </div>

Copy the code

provide/inject

// componeA
export default {
    provide(){
        return {
            foo:'bus'.// Change 'bus' to this to make the data responsive}}}//componeB
<template>
<div>
    {{foo}}
</div>
</template>
export default {
    inject: ['foo']// This field is not responsive. The parent component injected this field once. If you want this field to be responsive, the parent component needs to pass this reference data.
}
Copy the code

Event bus

// Bus: event dispatch, listening, and callback management
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))}}} Usage mode// main.js 
Vue.prototype.$bus = new Bus()
// child1 
this.$bus.$on('foo', handle) 
// child2 
this.$bus.$emit('foo'In practice, we usually use Vue instead of Bus because Vue already implements $ON and $emitCopy the code

slot

Slot syntax is a content distribution API implemented by Vue for composite component development. This technique is widely used in the development of common component library.

  1. Anonymous slot
// comp1 
<div>  
    <slot></slot> 
</div>
 
// parent 
<comp>hello</comp>

Copy the code
  1. Named slot: Distributes content to the location specified by the child component
// comp2 
<div> 
    <slot></slot>  
    <slot name="content"></slot> 
</div>
 
// parent 
<Comp2>    
<! -- Default slot with default parameter -->    
<template v-slot:default>A named slot</template>    
<! -- Named slot with slot name as parameter -->    
<template v-slot:content>Content...</template> 
</Comp2>

Copy the code

3. Scope slot: Distribute content using data in child components

// comp3 
<div>  
<slot :foo="foo"></slot> 
</div>
 
// parent 
<Comp3>    
    <! Set the value of v-slot as a scoped context object -->    
    <template v-slot:default="slotProps">Data from child components: {{slotProps. Foo}}</template>
</Comp3>
Copy the code