Vue component communication: parent and child, child and parent

1. Component communication

1.1 Component nesting

  • Vue provides great componentization ideas, and components improve code reusability.
  • Other components can be introduced into the component

1.2 Component nesting steps

  • Create parent and child components
  • Introduce child components in the parent component

1.3 Father and Son, Father and Son Communication

  • In vue.js, the relationship between parent and child components can be summarized as props down and events up
  • The parent component passes data down to the child component through props, and the child component sends messages to the parent component through events (the code will be detailed later)
  • Schematic diagram of father-son communication data transfer:
    Insert picture description here

1.4 Implementation case diagram

Insert picture description here
The following content is developed through this case. We hope to achieve:

  • When you click + after entering the content in the text box, the list of items below can be updated;
  • Click × after each item , the item can be deleted.

2. The parent component communicates with the child component

2.1 Father and child communication

  • To use the data of the parent component for the child component, we need to pass the props option of the child component. How to understand the props option?
    To make an analogy: a child is holding a big cloth bag and asks an adult for sugar to eat, and the adult puts the sugar in the big cloth bag. The
    prop option is this "big cloth bag". The parent component puts the data in the props option of the child component. The data is also available inside the sub-component, which is what is mentioned above-props down
  • Of course, the child component needs to use the data of the parent component, not only through the props option of the child component.
    In the template of the parent component, you need to dynamically bind the data of the parent component to the props of the child component, which is similar to binding to any ordinary html feature, which is to use v-bind, which is a colon (:) in short. In this way, whenever the data of the parent component changes, the change will also be transmitted to the child component.

2.2 Code implementation of parent and child and detailed description

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>父子通信</title>
  <script src="../js/vue.js"></script>
  <script>
    var todoAdd={
    
    
      props:["add_tasks"],
      data(){
    
    
        return{
    
    task:""}
      },
      template:`
      <div>
        <input type="text" v-model="task"><button @click="add">+</button>
      </div>`,
      methods:{
    
    
        add(){
    
    
          this.add_tasks.push(this.task);
          this.task="";
        }
      }
    }
    var todoItem={
    
    
      props:["t","i","item_tasks"],
      template:`
      <li>
        {
     
     {i+1}}-{
     
     {t}}<a href="javascript:;" @click="del">×</a>
      </li>`,
      methods:{
    
    
        del(){
    
    this.item_tasks.splice(this.i,1);}
      }
    };
    var todoList={
    
    
      props:["list_tasks"],
      template:`
      <ul>
        <todo-item v-for="(t,i) of list_tasks" :t="t" :i="i" :item_tasks="list_tasks"></todo-item>
      </ul>`,
      components:{
    
    todoItem}
    };    
    Vue.component("to-do",{
    
    
      data(){
    
    
        return{
    
    tasks:["吃饭","睡觉","打豆豆"]}
      },
      template:`
      <div>
        <h1>待办事项列表</h1>
        <todo-add :add_tasks="tasks"></todo-add>
        <todo-list :list_tasks="tasks"><todo-list>
      </div>`,    
      components:{
    
    todoAdd,todoList}
    })
  </script>
</head>
<body>
  <div id="app">
    <to-do></to-do>
  </div>
  <script>
    new Vue({
    
    
      el:"#app"
    })
  </script>
</body>
</html>

In order to facilitate understanding, explain the above code in a diagram:
Insert picture description here

Follow the picture aboveredLet's talk about the mark number in detail:

To facilitate understanding, we call todo the grandfather component, todoList the father component, and todoItem the son component

  1. In the template code (template) in the grandpa component todo——:list_tasks=“tasks”, the tasks in quotation marks are the data tasks of the grandpa component, and the list_tasks on the left side of the equal sign is the name given to the data in the father component todoList. To explain with the above analogy, adults call these candies toffees, and children call them white rabbit toffees. Although they are called differently, they refer to one thing! (It can also be called the same name, that is: tasks="tasks", but you need to know that the tasks on both sides of the equal sign have different meanings)
  2. In the parent component todoList——props:["list_tasks"], then the parent component has the variable list_tasks. What we need to pay attention to is: in the grandpa component todo, tasks is an array, and the array is a reference type, so there is an address in the tasks variable. Let’s assume this address is 0x1234, then the list_tasks we got in the father component todoList is also There is an address, and this address is also 0x1234. This means that the data we get from the grandpa component is not a copy, tasks and list_tasks point to the same address
  3. The list_tasks variable is used in the template code of the father component todoList
  4. The son component todoItem also needs to use grandpa’s tasks, but he can’t ask his grandpa for it, he asks his father for it, and his father also has it, but the name is list_tasks, and the son renames the data to be called item_tasks. Generate the list of transactions we want to get on the page through the v-for instruction
  5. The son component todoItem gets the data item_tasks through props, and item_tasks also points to address 0x1234
  6. After the event is triggered, the son component todoItem calls its own method del to delete the data in item_tasks. Because tasks, list_tasks, and item_tasks all point to an address, the trigger event affects the data in the grandpa component todo.

The same is true for the subcomponent todoAdd, so I won’t repeat it~

Say more heregreenThe code at the mark:

  • The son component todoItem needs to use the t and i variables of the father component todoList . The father component uses the code——:t=“t” :i=“i” to dynamically bind the data to the props of the son component, the equal sign on both sides t and i have different meanings, as mentioned above.

3. The child component communicates with the parent component

After learning the above content, the internal methods in the child component can use the data in the parent component in the above way. But the add() method and del() method in the above chestnut are scattered inside each sub-component. If there are more sub-components and methods, it will be difficult for us to maintain later. Therefore, if we put all the methods in the parent component, if the child component needs to use it, the method in the parent component will be triggered in a certain way. This is the communication between the child component and the parent component.

3.1 Child-father communication

  • The parent component uses props to pass data to the child component, but if the child component wants to pass data back, what should be done? That is a custom event!
    • Use $on (event name) to listen for events
    • Use $emit (event name) to trigger the time
  • Note that you cannot use $on to listen to events thrown by child components, but must use v-on binding directly in the template (v-on abbreviation @)
  • In the parent component: bind an event to the child component
<child @事件名称="方法名称(参数)"></child>
  • Within the child component: trigger the event specified by the parent component in the child component
this.$emit("事件名称")

3.2 Code implementation of child and parent and detailed description

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>子父通信</title>
  <script src="../js/vue.js"></script>
</head>
<script>
  var todoAdd={
    
    
    template:`
    <div>
      <input type="text" v-model="task"><button @click="add">+</button>
    </div>`,
    data(){
    
    
      return{
    
    task:""}
    },
    methods:{
    
    
      add(){
    
    
        this.$emit("add",this.task);
        this.task="";
      }
    }
  }
  var todoItem={
    
    
    props:["t","i"],
    template:`
    <li>
      {
     
     {i+1}}-{
     
     {t}}<a href="javascript:;" @click="del">×</a>
    </li>`,
    methods:{
    
    
      del(){
    
    this.$emit("del");}
    } 
  };
  var todoList={
    
    
    props:["tasks"],
    template:`
      <ul>
        <todo-item @del="del(i)" v-for="(t,i) of tasks" :t="t"  :i="i"></todo-item>
      </ul>`,
    methods:{
    
    
      del(i){
    
    this.$emit("del",i);}
    },
    components:{
    
    
      todoItem
    }   
  };  
  Vue.component("to-do",{
    
    
    template:`
    <div>
      <h1>待办事项列表</h1>
      <todo-add @add="add"></todo-add>
      <todo-list @del="del" :tasks="tasks"><todo-list>
    </div>`, 
    data(){
    
    
      return{
    
    
        tasks:["吃饭","睡觉","打豆豆"]
      }
    },  
    methods:{
    
    
      add(task){
    
    
        this.tasks.push(task);
      },
      del(i){
    
    
        this.tasks.splice(i,1);
      }
    }, 
    components:{
    
    
      todoAdd,
      todoList
    }
  })
</script>
<body>
  <div id="app">
    <to-do></to-do>
  </div>
  <script>
    new Vue({
    
    
      el:"#app"
    })
  </script>
</body>
</html>

Also first explain the above code with a picture:
Insert picture description here
first lookredmark:

  1. When the button button is clicked, the child component todoAdd triggers its own method add()
  2. The child component todoAdd can use $emit to trigger a custom event of the parent component todo, the custom event name is add, this.task is the parameter
  3. The custom event (@add="add") is defined in the template code (template) of the parent component todo. The left side of the equal sign is the event name, and the right quotation mark is the method name in the triggered parent component.
  4. The add method in the parent component todo is executed, and new things are added to the page

Look againbluemark:
To facilitate understanding, we call todo the grandfather component, todoList the father component, and todoItem the son component

  1. When you click ×, the son component todoItem triggers its own method del()
  2. The son component todoItem uses $emit to trigger a custom event of the father component todoList, the custom event name is del
  3. The template code (template) of the parent component todoList defines a custom event (@del="del(i)"), the left side of the equal sign is the event name, and the right quotation mark is the method name of the triggered parent component todoList.
  4. The method del(i) in the father component todoList has a parameter i, i is the subscript of the element in the tasks array currently to be deleted (the tasks array is in the data attribute of the grandpa component), the method also uses $emit to trigger grandpa The custom event of the component todo, the custom event name is del, i is the parameter (note: not this.i)
  5. The custom event (@del=“del”) is defined in the template code (template) of the grandpa component todo. The left side of the equal sign is the event name, and the right quotation mark is the method name of the triggered grandpa component
  6. The del method in the grandpa component todo is executed, and the selected transaction will be deleted

Guess you like

Origin blog.csdn.net/weixin_44410783/article/details/113960268