This is the 7th day of my participation in the Gwen Challenge in November. Check out the details: The Last Gwen Challenge in 2021.

preface

In a blog on vue learning notes (8) component validation & communications, we’ve learned vue components in check and send messages to subcomponents parent components and subcomponents notify the parent component (parent-child communication component), on a blog also mentioned that the contents of the components is just beginning, and this chapter, the blog will focus on the interpretation of the vue – cli the components in the communication, After all, this is very common in future development. So let’s take a look at what you need to learn from this blog.

Objective in this chapter

  • Learn how to use vue-CLI parent components to pass information to child components
  • Learn to use vue-CLI neutron components to pass information to parent components
  • Learn to pass information using vue-CLI non-parent components

Vue-the parent component in the CLI passes information to the child component

Since vuE-CLI is mentioned to realize component communication, vue-CLI environment must be available. Users who have not built vue-CLI environment can refer to this blog to build vue-CLI project using Webstorm. This blog explains very thoroughly, you can first set up the environment, and then read this blog. Suppose our project is set up and the project directory structure is as follows

  • Create two components parent and child

We need to create two components in SRC /components/parent/ parentComponent. vue and ChildComponent. Vue

  • Write code in the respective components

ParentComponent.vue

<template> <div> <h1>{{title}}</h1> <! - note: Each component registration must have a root element --> <Child :message="message"></Child> </div> </template> <script> import Child from './ChildComponent' Export default {name: "ParentComponent", data() {return {title:' ParentComponent ', message: }, components:{Child}} </script> <style scoped> </style>Copy the code

Message is the information to be passed to the child component. The second step is to import the child component and register the child component. The third step is to bind the information to the component.

conclusion

  • Define the data
  • Import components and register components
  • Data binding to components

ChildComponent.vue

<template>
    <div>
      <! Note that each component registration must have a root element -->
      <h1>{{title}}</h1>
      <span>The parent component passes the following message :{{message}}</span>
    </div>
</template>
​
<script>
    export default {
      name: "ChildComponent".props: ['message'].// Use props to receive information passed by the parent component
      data(){
          return{
            title:'This is a child component',
​
          }
      }
    }
</script>
​
<style scoped>
​
</style>
Copy the code

In the child component we use props to receive information from the parent component and then render the data.

index.vue

import Vue from 'vue'
import Router from 'vue-router'
import HelloWorld from '@/components/HelloWorld'
import Hi from '@/components/Test/Hi'
import parent from '@/components/parent/ParentComponent'
Vue.use(Router)
​
export default new Router({
  routes: [{path:'/'.component:parent,
      name:parent
    }
  ]
})
Copy the code

Results:

Using vue-CLI to implement the parent component to pass information to the child component.

Vue-a child component in the CLI passes information to the parent component

We learned that the parent component passes information to the child component, then we need to learn that the child component passes information to the parent component, again we use the above two components, after updating the code

ParentComponent.vue

<template>
    <div>
      <h1>{{title}}</h1>
      <! Note: Each component registration must have a root element -->
      <Child :message="message" @send="getChildMsg"></Child>
      <h1>Message from child component :{{childMsg}}</h1>
    </div>
</template>
​
<script>
  import Child from './ChildComponent'
    export default {
        name: "ParentComponent".data() {
          return {
            title:'This is the parent component'.message: 'I'm the parent component'.childMsg:' '}},components:{
          Child
        },
        methods: {getChildMsg(data){
            this.childMsg=data;
          }
        }
    }
</script>
​
<style scoped>
​
</style>
Copy the code

In the parent component, we redefine a new property (childMsg) to receive the message from the child component. We know that the child component sends the event to the parent component as send, and then call SEND to receive the data from the child component

ChildComponent.vue

<template>
    <div>
      <! Note that each component registration must have a root element -->
      <h1>{{title}}</h1>
      <span>The parent component passes the following message :{{message}}</span>
      <input type="button" value="Pass information to parent" @click="sendMsgToParent">
    </div>
</template>
​
<script>
    export default {
      name: "ChildComponent".props: ['message'].// Use props to receive information passed by the parent component
      data(){
          return{
            title:'This is a child component'.fromChildMsg:'I am a message from a child component',}},methods: {sendMsgToParent(){
          this.$emit('send'.this.fromChildMsg);
        }
      }
    }
</script>
​
<style scoped>
​
</style>
Copy the code

A new attribute (fromChildMsg) has been redefined in the child component. This attribute needs to be passed to the parent component, which then uses this.$emit() to give the event name and data to the parent component through the button click event. The parent component registers the send method to receive the message from the child component.

Results:

At this point, the parent component passing information to the child component and the child component passing information to the parent component are all explained, can be said to be very detailed, I wrote each step is very clear

Conclusion:

  • The parent component passes information to the child component via props
  • Child components send messages to parent components via this.$emit(‘ event name ‘, value 1, value 2,….)

Vue-non-parent components in the CLI pass information

In component communication, in addition to the parent component passing information to the child component and the child component passing information to the parent component, there is also non-parent component communication, which I will also go into in great detail.

  • Create a directory for non-parent component communication

In the SRC/components to build other directories and two components: BrotherComponent. Vue, SisterComponent. Vue, and create an event under SRC/assets. Js file and directory created are as follows

(2) Event.js acts as a bus

In the event.js file we just create a new Vue instance, which will act as a bus bridge between components, the central event bus, to connect brotherComponent.vue to sisterComponent.vue.

event.js

/ / way
import Vue from 'Vue'
export  default  new Vue
Let bus=new Vue export default bus */
Copy the code

BrotherComponent.vue

<template> <div> <h1> <input type="button" @click="sendMsg" value=" send message to sister component "> <sister></sister> </div> </template> <script> // import bus from '.. /.. /assets/event' // Import sister from './SisterComponent' export default {name: "BrotherComponent", data(){return{tips:'I am your brother'}}, components:{sister // methods:{ sendMsg(){ bus.$emit('send',this.tips); } } } </script> <style scoped> </style>Copy the code

In this component, we first import the bus and sister component, and then register the sister component. In the sendMsg function that responds to the click event, we use $emit to trigger a custom send event and pass a string argument.

This parameter is the value of the sister component that needs to be passed.

The $emit instance method fires events on the current instance (bus in this case), and additional arguments are passed to the listener callback

SisterComponent.vue

<template>
  <div>
    <h1>Sister components</h1>
    <span>{{msg}}</span>
  </div>
</template>
​
<script>
  import bus from '.. /.. /assets/event'
    export default {
        name: "SisterComponent".data(){
          return{
            msg:' '}},methods: {getMsg(){
          bus.$on('send'.data= >{
            this.msg=data; })}},mounted(){
          this.getMsg();
      }
    }
</script>
​
<style scoped>
​
</style>
Copy the code

In mounted, we hear send and pass the string argument to the $ON callback. Mounted is a hook function in the Vue lifecycle.

Mounted function (MOUNTED) is called after the document is loaded. On: listens for custom events on the current instance (bus). Events can be made by on: listening for custom events on the current instance (in this case, bus). Events can be made by on: listening for custom events on the current instance (in this case, bus). Events can be emitted by emit, and the callback function receives additional arguments from all incoming event triggering functions ($emit).

index.js

import Vue from 'vue'
import Router from 'vue-router'
import HelloWorld from '@/components/HelloWorld'
import Hi from '@/components/Test/Hi'
import parent from '@/components/parent/ParentComponent'
import brother from '@/components/other/BrotherComponent'
Vue.use(Router)
​
export default new Router({
  routes: [{path:'/'.component:brother,
      name:brother
    }
  ]
})
Copy the code

The results of

Conclusion:

  • Create an event bus, such as event.js in the example, and use it as a communication bridge
  • Emit a custom event with bus.$emit on the component that needs to send the value and pass the parameter
  • Use bus.$on to listen for custom events in components that need to receive data and handle the parameters passed in the callback function

At this point, the basic communication modes of components have been explained. After learning more advanced content, new communication modes of components will be added. There are three communication modes: parent component transmits information to child component, child component transmits information to parent component, and non-parent component transmits information. This is a short list of details, but some examples will be provided to consolidate your knowledge of components.

Comprehensive practice

Normal version of the task list

This version of the to-do list was covered in the last blog post, so why revisit it here? Bloggers feel that the last blog didn’t go into much detail, and this blog also has other versions of the to-do list, so combining the two makes learning easier.

<! DOCTYPE HTML > < HTML > <head> <meta charset="UTF-8"> <title> Generic task list </title> </head> <body> <div id="app"> <input Type ="text" v-model="newTask" @keyup.enter="addNew" placeholder=" placeholder task "/> <todo-item v-for="(item,index) of tasks" :title='item' :index="index" @remove="removeItem"></todo-item> </div> <script src=".. /js/vue.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> let vm=new Vue({ el:'#app', Data :{newTask:'', tasks:[' watch a movie ',' read a book ',' treat a friend to dinner '],}, methods:{addNew(){this.tasks.unshift(this.newtask); // Add the task this.newTask= "" to the top of the task list; }, removeItem(index){if(confirm(' Are you sure you want to delete it? ')){ this.tasks.splice(index); } } }, computed:{ }, components:{ 'todoItem':{ props:['title',"index"], template:'<li><span>{{title}}</span><button @click="sendMsg(index)">X</button></li>', methods:{ sendMsg(index){ console.log(index); this.$emit('remove',index); } } } } }) </script> </body> </html>Copy the code

Step analysis:

  • 1. Define the task to add (newTask) and the entire task list (Tasks), and add a task to the task list when you press Enter.
  • 2. Define the task list component and pass in the task list and index.
  • 3. Define the event this.$emite(‘remove’,index) to notify the parent.
  • 4. The parent component receives the event and subscript index notified by the child component and processes it accordingly.

Vue-cli version task list

The normal version of the task list we end, the next need to implement the vue-CLI task list, the normal version of the task list is not much different, just change a way of writing, the principle is still the same (change the same), so follow me to see it!

  • 1. Create directories and components

Create a taks directory and parentComponent. vue and childComponent. vue under SRC /components

  • 2. Write code in the corresponding component

ParentComponent.vue

<template>
  <div>
    <h1>This is the parent component</h1>
    <input type="text" v-model="newTask" @keyup.enter="addNew" placeholder="Please enter the task you want to add.">
    <child v-for="(item,index) of tasks" :item="item" :index="index" @remove="removeItem" :key="index"></child>
  </div>
</template>
​
<script>
    import Child from './ChildComponent'
    export default {
        name: "ParentComponent".components:{
          Child     // Register child components
        },
      data(){
          return{
            newTask:' '.tasks: ['Buy a book'.'Watch a movie'.'Write a blog'],}},methods: {addNew(){
          this.tasks.unshift(this.newTask);
          this.newTask="";
        },
        removeItem(index){  // Delete the task
          if(confirm('Are you sure you want to delete it? ')) {this.tasks.splice(index);
          }
        }
      }
    }
</script>
​
<style scoped>
​
</style>
Copy the code
  • The parent component first imports and registers the child components, then defines the list of tasks to be added (newTask) and the entire list of tasks (tasks). The addNew method in the input box adds a newTask list to tasks when we press enter.
  • Once the subcomponents are registered, they are passed the task list items and the index for each task list item.
  • The parent component receives the child component’s notification method (remove) and then processes the task list accordingly.

ChildComponent.vue

<template>
    <div>
      <li>{{item}}<button @click="sendMsg(index)">X</button></li>
    </div>
</template>
​
<script>
    export default {
        name: "ChildComponent",
        props:['item','index'],
      data(){
          return{
​
          }
      },
      methods:{
        sendMsg(index){
            this.$emit('remove',index);
          }
      }
    }
</script>
​
<style scoped>
​
</style>
Copy the code
  • In the child component, we first use props to receive two parameters, item and index, from the parent component.
  • Define a method that notifies the parent component of which task list needs to be deleted.

index.js

import Vue from 'vue'
import Router from 'vue-router'
import  parent from '@/components/task/ParentComponent'
Vue.use(Router)
​
export default new Router({
  routes: [
    {
      path:'/',
      component:parent,
      name:parent
    }
  ]
})
Copy the code

So we’re done with the vue-CLI version of the to-do list, but as always,

Parent component passes information to child component using props, child component passes information to parent component using this.$emit(‘ event name ‘, value 1, value 2…)

General version of shu tax

This case is similar to the previous one, the principle is the same, so let’s take a look!

<! DOCTYPEhtml>
<html>
    <head>
        <meta charset="UTF-8">
        <title>General version of shu tax</title>
    </head>
    <body>
        <div id="app">
            <h2>{{name}}</h2>
            <h3>Total: {{total}}</h3>
            <me-tax @tax="undateTotal" name="Zhaoyun" :unit="unit"></me-tax>
            <me-tax @tax="undateTotal" name="D" :unit="unit"></me-tax>
            <me-tax @tax="undateTotal" name="Zhang fei" :unit="unit"></me-tax>
            <me-tax @tax="undateTotal" name="Guan yu" :unit="unit"></me-tax>
            <me-tax @tax="undateTotal" name="Huang zhong" :unit="unit"></me-tax>
            <h3>{{msg}}</h3>
        </div>
        <script src=".. /js/vue.js" type="text/javascript" charset="utf-8"></script>
        <script type="text/javascript">
            Vue.component('me-tax', {template:'<button @click="upTax">{{money}}</button>'.data(){
                    return{
                        money:0,}},props: ['name'.'unit'].methods: {upTax(){
                        this.money+=this.unit;    // Total tax revenue
                        this.$emit('tax', {name:this.name,money:this.money});// Notify the parent component}}})let vm=new Vue({
                el:'#app'.data: {name:'Shu pays taxes'.total:0.unit:10.// The amount of each tax
                    msg:' '
                },
                methods: {undateTotal(obj){
                        this.total+=this.unit;
                        this.msg=obj.name+"Tax paid, tax paid."+obj.money; }},computed: {}})</script>
    </body>
</html>
Copy the code

The results of

Thought analysis

  • In the parent component, define the total of taxes (total) and the number of taxes per tax (unit)
  • Define the child component, accept the two parameters name and unit passed by the parent component, define a method to calculate the total amount of its tax and notify the parent component tax
  • After receiving the notification from the child, the parent calculates the sum of the taxes paid and displays the tax that shu will pay

Vue – CLI version of Shu tax

Vue-cli version of the Kingdom of Shu to pay taxes, we also follow the steps, step by step to analyze

  • Create a new directory and define six components

New money in SRC/components directory and UnitTotalComponent vue, UnitComponentA. Vue, UnitComponentB. Vue, UnitComponentC. Vue, UnitComponentD. Vue, UnitComponent. vue has six components. The directory structure is as follows

Here we split the components. Here we copy the same components, and here we have one file for one component

  • Write code in the corresponding component

UnitTotalComponent.vue

<template>
  <div>
    <h1>{{name}}</h1>
    <h3>Total taxes: {{total}}</h3>
    <A title="Zhang fei" :unit="unit" @tax="updateTotal"></A>
    <B title="Guan yu" :unit="unit" @tax="updateTotal"></B>
    <C title="D" :unit="unit" @tax="updateTotal"></C>
    <D title="Zhaoyun" :unit="unit" @tax="updateTotal"></D>
    <E title="Huang zhong" :unit="unit" @tax="updateTotal"></E>
    <h3>{{msg}}</h3>
  </div>
</template>
​
<script>
  // Import the corresponding component
  import A from './UnitComponentA'
  import B from './UnitComponentB'
  import C from './UnitComponentC'
  import D from './UnitComponentD'
  import E from './UnitComponentE'
    export default {
        name: "UnitTotalComponent".data(){
          return{
            name:'Shu pays taxes'.total:0.unit:10.// The amount of each tax
            msg:' '}},components: {// Register the component
          A,
          B,
          C,
          D,
          E
      },
        methods: {updateTotal(obj){
            this.total+=this.unit;
            this.msg=obj.name+'Tax paid successfully, tax paid'+obj.money;
          }
        }
    }
</script>
​
<style scoped>
​
</style>
Copy the code
  • Five components are first imported and registered in the UnitTotalComponent component
  • Define the amount of data to be passed (unit per tax)
  • According to the method of each sub-component notification will be calculated the sum of the tax paid, and show which shu general

UnitComponentA.vue

<template>
    <div>
      <button @click="upTax">{{money}}</button>
    </div>
</template>
​
<script>
    export default {
        name: "UnitComponentA".props: ['title'.'unit'].methods: {upTax(){
          this.money+=this.unit;
          this.$emit('tax', {name:this.title,money:this.money}); }},data(){
          return{
            money:0,
          }
      }
    }
</script>
​
<style scoped>
​
</style>
Copy the code
  • The UnitComponentA component receives the title and Unit properties passed by the parent component
  • Define the method tax that notifies the parent component, passing in parameters and methods

UnitComponentB.vue

<template>
  <div>
    <button @click="upTax">{{money}}</button>
  </div>
</template>
​
<script>
    export default {
      name: "UnitComponentB".props: ['title'.'unit'].methods: {upTax(){
          this.money+=this.unit;
          this.$emit('tax', {name:this.title,money:this.money}); }},data(){
        return{
          money:0,
        }
      }
    }
</script>
​
<style scoped>
​
</style>
Copy the code
  • The UnitComponentB component receives the title and Unit properties passed by the parent component
  • Define the method tax that notifies the parent component, passing in parameters and methods

UnitComponentC.vue

<template>
  <div>
    <button @click="upTax">{{money}}</button>
  </div>
</template>
​
<script>
    export default {
        name: "UnitComponentC".props: ['title'.'unit'].methods: {upTax(){
          this.money+=this.unit;
          this.$emit('tax', {name:this.title,money:this.money}); }},data(){
        return{
          money:0,
        }
      }
    }
</script>
​
<style scoped>
​
</style>
Copy the code
  • The UnitComponentC component receives the title and Unit properties passed by the parent component
  • Define the method tax that notifies the parent component, passing in parameters and methods

UnitComponentD.vue

<template>
  <div>
    <button @click="upTax">{{money}}</button>
  </div>
</template>
​
<script>
    export default {
        name: "UnitComponentD".props: ['title'.'unit'].methods: {upTax(){
          this.money+=this.unit;
          this.$emit('tax', {name:this.title,money:this.money}); }},data(){
        return{
          money:0,
        }
      }
    }
</script>
​
<style scoped>
​
</style>
Copy the code
  • The UnitComponentD component receives the title and Unit properties passed by the parent component
  • Define the method tax that notifies the parent component, passing in parameters and methods

UnitComponentE.vue

<template>
  <div>
    <button @click="upTax">{{money}}</button>
  </div>
</template>
​
<script>
    export default {
        name: "UnitComponentE".props: ['title'.'unit'].methods: {upTax(){
          this.money+=this.unit;
          this.$emit('tax', {name:this.title,money:this.money}); }},data(){
        return{
          money:0,
        }
      }
    }
</script>
​
<style scoped>
​
</style>
Copy the code
  • The UnitComponentE component receives the title and Unit properties passed by the parent component
  • Define the method tax that notifies the parent component, passing in parameters and methods

index.js

import Vue from 'vue'
import Router from 'vue-router'
import total from '@/components/money/UnitTotalComponent'
Vue.use(Router)
​
export default new Router({
  routes: [{path:'/'.component:total,
      name:total
    }
  ]
})
Copy the code

The results of

Vue component communication here is about to come to an end, the knowledge points explained also explained completed, anyway this blog you repeatedly go to see there will always be harvest. It is not difficult to learn, task list and Shu tax these two cases will learn components communication together, learning is also very convenient.

conclusion

This blog focuses on three things: a parent sends information to a child, a child sends information to a parent, non-parent components communicate,

  • The parent component passes information to the child component mainly through props

  • $emit(‘ event name ‘, value 1, value 2…)

Emit () for transmitting data, bus.emit() for receiving data, bus.emit() for receiving data, bus.on() for receiving data.