vue components and communication slots

Posted by tomtomdotcom on Wed, 29 Dec 2021 11:50:25 +0100

catalogue

Component communication

The parent component passes data to the child component

 props

The child component passes data to the parent component

Multiple parameters

Communication between non parent and child components

How many ways can Vue components communicate with each other?  

slot

Anonymous slot

Named slot

Slot scope

Component communication

The parent component passes data to the child component

1. From father to son: the father changes, the son changes, the son changes, the father remains unchanged, and an error is reported
2. Parent to child: when the parent changes, the child changes, the child changes, and the parent changes, an object needs to be passed
3. Transfer from parent to child: the parent changes, the child remains unchanged, the child changes, and the parent remains unchanged. It is necessary to transfer data to the new data attribute in the child component

Parent

Parent.vue
<template>
  <div class="alert alert-info">
      <h2>Parent component</h2>
      <input v-model="name" />
      <!--1.Father to son: Paternal change,Sub change,Sub change,Father invariant,And report an error.  -->
      <div>name The value of is:{{name}}</div>
      <hr />
      <!-- 2.Father to son:Paternal change,Sub change,Sub change,Paternal change,An object needs to be passed -->
      <input v-model="person.name" />
      <div>person Object name Value is:{{person.name}}</div>
      <hr />
      <!-- 3.Father to son: Paternal change,Son invariant,Sub change, Father invariant, The data needs to be passed to the new in the subcomponent data attribute-->
     <input v-model="age" />
      <div>age The value of is:{{age}}</div>
      <!-- 3.Component call -->
      <!-- Find the association point of parent and child components -->
    <v-child :a="10" :num="666" :name="name" :person="person" :age="age"></v-child>
  </div>
</template>

<script>
// 1. Lead in components
import vChild from './Child'
export default {
    data(){
        return{
            name:'Christmas Eve',
            person:{
                name:'Wang Yibo',
            },
            age:20,
        }
    },
    // 2. Component registration
    components:{
        vChild
    }
}
</script>

<style>

</style>

Children

<template>
  <div class="well">
      <h2>Subcomponents</h2>
      <div>num The value of is:{{num}}</div>
      <input type="text" v-model="name">
      <div>name The value of is:{{name}}</div>
      <hr>
      <input v-model="person.name" />
      <div>person Object name Value is:{{person.name}}</div>
      <hr>
      <input v-model="newAge" />
      <div>newAge The value of is:{{newAge}}</div>
  </div>
</template>

<script>
export default {
    props:['num','a','name','person','age'],//props option: specially used to receive the data passed from the parent component to the child component
    data(){
        return {
            newAge:'',
        }
    },
    mounted(){
        this.newAge = this.age;
    }
}
</script>

<style>

</style>

Summary:
Find the association point of parent and child components
Parent component: passing data through custom attributes
Subcomponent: accept data through props option
  
2) ref communicates with applicable parent-child components of $parent / $children
ref: if used on ordinary DOM elements, the reference points to
DOM element; If used on a child component, the reference points to the component instance
$parent / $children: access parent / child instances

 props

Function: when the parent component passes to the child component, it is accepted through the props option
Value of props: object | array

If the value of props is: {}, it means that data type verification can be done in props
Verification type: Number String Array Object Function Boolean

Required: # required
Type: # type
Validator: # validator
Default: # default

Child.vue
<template>
  <div class="well">
      <h2>Subcomponents</h2>
      <div>name The value of is:{{name}}</div>
      <div>newAge The value of is:{{newAge}}</div>
      <div>phone The value of is:{{phone}}</div>
  </div>
</template>

<script>
export default {
    // props for data verification
    props:{
        name:{
            type:String,//Type: String
            required:true,//Required 
        },
        newAge:{
            type:Number,//Type: Number
            default:18,//Default value
            validator:function(age){//Validator: validator
              return 0 <= age <= 100
            }
        },
        phone:{
            type:[String,Number],//Type: or relationship 
        }
    }
}
</script>

<style>

</style>

The child component passes data to the parent component

summary
Subcomponent: pass custom events by triggering $emit
Parent component: trigger a custom event to trigger the event function of the parent component, and accept data through parameters
    
How to accept data from subcomponents:
        1. Show receive: $event in event function
        3. Hermit reception: receive directly through formal parameters at the sound of event function

 

Parent
<template>
  <div class="alert alert-info">
      <h2>Parent component</h2>
      <div>name The value of is:{{name}}</div>
      <!-- Association points of parent-child components -->
      <!-- @message Indicates that a custom event was triggered
            @message amount to @click
       -->
       <!-- Through display $event Accept data -->
      <v-child @message="send($event)"></v-child>
      <hr />
      <!-- Receive data through Hermits -->
      <v-child @message="send"></v-child>
  </div>
</template>

<script>
import vChild from './Child'
export default {
    data(){
        return{
            name:'',
        }
    },
    methods:{
        send(name){
            this.name = name;
        }
    },
    components:{
        vChild
    }
}
</script>

<style>

</style>
Child
<template>
  <div class="well">
      <h2>Subcomponents</h2>
      <input type="text" v-model="name" @change="send1">
      <div>name The value of is:{{name}}</div>
      <button @click="send">send out</button>
  </div>
</template>

<script>
export default {
    data(){
        return{
            name:'Wang Chengyu',
        }
    },
    methods:{
        send(){
            // Trigger $emit event
            /**
             * Parameter 1: custom event name
             * Parameter 2: transferred data
            */
            this.$emit('message',this.name);
        },
        send1(){
            this.$emit('message',this.name);
        }
    },
    watch:{
        name(){
            this.$emit('message',this.name);
        }
    },
    mounted(){
        console.log(this);
    }
}
</script>

<style>

</style>

Multiple parameters

<template>
  <div class="alert alert-info">
      <h2>Parent component</h2>
      <div>name The value of is:{{name}}</div>
      <div>age:{{age}}</div>
      <!-- Association points of parent-child components -->
      <!-- @message Indicates that a custom event was triggered
            @message amount to @click
       -->
       <!-- Through display $event Accept data -->
      <v-child @message="sendP(arguments)"></v-child>
      <hr />

  </div>
</template>

<script>
import vChild from './Child'
export default {
    data(){
        return{
            name:'',
            age:''
        }
    },
    methods:{
        sendP(data){
            //Pass multiple parameters
           
            this.name = data[0],
            this.age = data[1]
         
        }

    },
    components:{
        vChild
    }
}
</script>

<style>

</style>

Communication between non parent and child components

There are three ways:

1.eventBus A component -- > B component exists at the same time, and the transmission of events is realized in the component,

2. Local storage: localStorage sessionStorage

3.vuex status management

Vuex is suitable for parent-child, intergenerational and sibling component communication. Vuex is designed for Vue JS application development state management mode. The core of every vuex application is the store. The "store" is basically a container that contains most of the states in your application. Vuex's state store is responsive. When Vue components read the status from the store, if the status in the store changes, the corresponding components will be updated efficiently. The only way to change the state in the store is to explicitly commit the mutation. This makes it easy for us to track the changes of each state.

step

Instantiate Vue on Vue's prototype chain

main.js
Vue.prototype.$eventBus = new Vue();

Trigger custom events from by triggering the $emit method

this.$eventBus.$emit('name of custom event ', parameter)

Monitor the triggering of custom events through $on

this.$eventBus.$on('name of custom event ', (E) = >{
/ / e: accept passed data
})

 

Box1.vue
<template>
  <div class="well">
      <h2>box1 assembly</h2>
      <div>name The value of is:{{name}}</div>
      <button @click="send">send out</button>
  </div>
</template>

<script>
export default {
  data(){
    return{
      name:'Li Jiaqi'
    }
  },
  methods:{
    send(){
      /**
       * Trigger custom event
       * Parameter 1: custom event name
       * Parameter 2: transferred data
      */
    //  this.$eventBus === new Vue()
      this.$eventBus.$emit('message',this.name);
    }
  },
  mounted(){
    // console.log(this.a);
    // console.log(this.$eventBus);
    // Implement listening
    this.$eventBus.$on('message',(e)=>{
      this.name = e;
    })
  }
}
</script>

<style>
Box2
<template>
  <div class="well">
      <h2>box2 assembly</h2>
      <input type="text" v-model="name">
      <div>name The value of is:{{name}}</div>
  </div>
</template>

<script>
export default {
  data(){
    return{
      name:'',
    }
  },
  watch:{
    name(){
      this.$eventBus.$emit('message',this.name)
    }
  },
  mounted(){
    // Listen for the triggering of the message event
    /**
     * Listen for the triggering of user-defined events
     * Parameter 1: listen to user-defined event name
     * Parameter 2: callback
    */
  //  this.$eventBus  ===  new Vue()
    this.$eventBus.$on('message',(e)=>{
      // console.log('monitored ');
      this.name =  e;
    })
    // console.log(this.a);
    // console.log(this.$eventBus);
  }
}
</script>

<style>

</style>
Box3
<template>
  <div class="well">
      <h2>box3 assembly</h2>
      <div>name The value of is:{{name}}</div>
  </div>
</template>

<script>
export default {
  data(){
    return{
      name:'',
    }
  },
  mounted(){
    // Implement listening
    this.$eventBus.$on('message',(e)=>{
      this.name = e;
    })
  }
}
</script>

<style>

</style>

How many ways can Vue components communicate with each other?  

Communication between Vue components is one of the knowledge points often tested in interviews. This question is a bit similar to an open question. The more you answer, the more points you will get, indicating that you are more proficient in Vue. Vue inter component communication only refers to the following three types of communication: parent-child component communication, inter generation component communication and brother component communication. Next, we will introduce each communication mode and explain which type of inter component communication this method can be applied to.

(1) props / $emit is applicable to parent-child component communication. This method is the basis of Vue components. I believe most students can hear it in detail, so I won't give an example here.

(2) ref communication with parent-child components applicable to $parent / $children ref: if used on ordinary DOM elements, the reference points to DOM elements; if used on child components, the reference points to component instances $parent / $children: access parent / child instances

(3) EventBus ($emit / $on) is applicable to parent-child, intergenerational and sibling component communication. This method uses an empty Vue instance as the central event bus (event center) to trigger and listen to events, so as to realize the communication between any component, including parent-child, intergenerational and sibling components.

(4) Vuex is suitable for parent-child, intergenerational and sibling component communication. Vuex is a state management mode specially developed for Vue.js applications. The core of each vuex application is the store. The "store" is basically a container, which contains most of the states of your application. Vuex's state store is responsive. When Vue components read the status from the store, if the status in the store changes, the corresponding components will be updated efficiently. The only way to change the state in the store is to explicitly commit the mutation. This makes it easy for us to track the changes of each state.

 

slot

The system provides a component slot: notch
Slot, also known as notch

Anonymous slot

Index
<template>
  <div class="alert alert-info">
      <h2>Parent component</h2>
      <v-child>
          <div>Live delivery player:Wang Chengyu,Li Zhiyuan</div>
          <h1>This is the first level title</h1>
      </v-child>
  </div>
</template>

<script>
import vChild from './Child'
export default {
    components:{
        vChild
    }
}
</script>

<style>

</style>
Child
<template>
  <div class="well">
      <h2>Subcomponents</h2>
      <!-- A component is provided in the system slot:Notch -->
      <!-- Anonymous notch -->
      <slot></slot>
      <slot></slot>
  </div>
</template>

<script>
export default {

}
</script>

<style>

</style>

Named slot

<!-- This is the name and is called a named notch -- >
 <slot name="students"></slot>

 

Index
<template>
  <div class="alert alert-info">
      <h2>Parent component</h2>
      <!-- 1.Anonymous notch -->
      <!-- <v-child>
          <div>Live delivery player:Wang Chengyu,Li Zhiyuan</div>
          <h1>This is the first level title</h1>
      </v-child> -->

      <v-child1>
        <ul slot="stars">
          <li>Weiya</li>
          <li>Li Jiaqi</li>
          <li>snow pear</li>
        </ul>

      <ol slot="students">
          <li>Classmate Zhang</li>
          <li>Classmate Li</li>
          <li>Classmate Wang</li>
      </ol>

      </v-child1>
  </div>
</template>

<script>
// import vChild from './Child'
import vChild1 from './Child1'
export default {
    components:{
        // vChild
        vChild1
    }
}
</script>

<style>

</style>
Child1
<template>
  <div class="well">
      <h2>Subcomponents</h2>
      <!-- For the notch, this is the name,Named notch -->
      <slot name="students"></slot>
      <slot name="stars"></slot>
  </div>
</template>

<script>
export default {

}
</script>

<style>

</style>

Slot scope

Scope slot is a slot that the parent component passes to the child component when calling the child component. This slot is a scope slot. This slot must be placed in the template tag. At the same time, it declares that the data received from the child component is placed in a user-defined attribute, and defines the rendering method of the data.

Index
<template>
  <div class="alert alert-info">
      <h2>Parent component</h2>
      <!-- 1.Anonymous notch -->
      <!-- <v-child>
          <div>Live delivery player:Wang Chengyu,Li Zhiyuan</div>
          <h1>This is the first level title</h1>
      </v-child> -->

    <!-- 2.Named notch -->
      <!-- <v-child1>
        <ul slot="stars">
          <li>Weiya</li>
          <li>Li Jiaqi</li>
          <li>snow pear</li>
        </ul>

      <ol slot="students">
          <li>Classmate Zhang</li>
          <li>Classmate Li</li>
          <li>Classmate Wang</li>
      </ol> 
      </v-child1>-->
      <v-child2>
           <!-- 
               1.scope Variable customization
               2.scope The accepted value is a pair of objects: {row:{id:1,name:'toothpaste',price:20.00}}
            -->
           <template v-slot="scope">
               <div>number:{{scope.row.id}}</div>
               <div>Trade name:{{scope.row.name}}</div>
               <div>commodity price:{{scope.row.price}}</div>
           </template>
      </v-child2>
  </div>
</template>

<script>
// import vChild from './Child'
// import vChild1 from './Child1'
import vChild2 from './Child2'
export default {
    components:{
        // vChild
        vChild2
    }
}
</script>

<style>

</style>
Child2
<template>
  <div class="well">
      <h2>Subcomponents</h2>
      <!-- <ul>
          <li v-for="item in list" :key="item">
               Notch 
              <slot :row="item"></slot>
          </li>
      </ul> -->

      <ul>
          <li v-for="item in goods" :key="item.id">
              <!-- Set notch -->
              <slot :row="item"></slot>
          </li>
      </ul>
  </div>
</template>

<script>
export default {
    data(){
        return{
            list:['bmw','Benz','Phoenix Bicycle','audi'],
            goods:[
                {id:1,name:'toothpaste',price:20.00},
                {id:2,name:'toothbrush',price:10.00},
                {id:3,name:'Wash basin',price:10.00},
                {id:4,name:'Facial Cleanser',price:70.00},
            ]
        }
    }
}
</script>

Topics: Javascript Front-end Vue.js