Parent-child component communication

1. Parent and child components pass data through prop

A parent component can pass a piece of data to a child component. This piece of data can be dynamic, and when the parent component’s data changes, the child component receives it as well.

The child passively receives the parent’s data and does not change it.

The scope of a component instance is isolated, and the parent cannot directly use the child’s data, nor can the child directly use the parent’s data.

The parent component passes data to the child component when calling it:

<template id="father">
        <div class="father"> <p> I am the parent component and this is my fMsg: {{fMsg}}</p> <inputtype = "text" v-model = "fMsg">
            <hr>
            <son msg = "Hello"></son>
        </div>
    </template>
Copy the code

When the parent component passes data to the child component, the child component needs to use the props attribute to determine its own expected data. If the child does not receive the data through the props attribute, the data is placed on the outermost root element as a custom attribute.

The child component accepts data from the parent component via props and uses it via {{MSG}}

components:{
            son:{
                template:"
      
I am a son child! This is what the parent component passed me: {{MSG}}
"
// MSG props:["msg"]}}Copy the code

2. The parent component passes its variables to the child component via the V-bind directive

We can use V-bind to dynamically bind prop to the parent component’s data. Whenever the parent component’s data changes, that change is also transmitted to the child component.

<template id="father">
        <div class="father"> <p> I am the parent component and this is my fMsg: {{fMsg}}</p> <inputtype = "text" v-model = "fMsg"> <hr> <! -- <son msg ="Hello"></son> -->
            <son :msg = "fMsg"></son>
        </div>
    </template>
Copy the code

If if the parent component passes a property to the child component with the key ‘-‘

<son :f-msg = "fMsg"></son>
Copy the code

Child components are received and used in a small hump pattern

components:{
            son:{
                template:"
      
I am a son child! This is what the parent component passed me: {{fMsg}}
"
// MSG props:["fMsg"]}}Copy the code

3. Prop verifies the passed data

We can specify validation rules for component prop. Vue will issue a warning if the incoming data does not meet the requirements. This is useful for developing components for others to use

The authentication includes type authentication, mandatory authentication, default authentication, and custom authentication

Type validation

Num: [Number,String], num: [Number,String],Copy the code

Specifies that the numeric type passed must be number, otherwise the system will report an error

Will pass validation

Specifies that the parent must pass the value to the child

// required validation // num:{// required:true
// }
Copy the code

Default Settings

When the parent does not pass this value to the child, give the child a default value

Num :{// default:100 //}Copy the code

Custom authentication

Num :{validator(val){return val > 100
                                }
                            }
Copy the code

Specifies that the value passed must be greater than 100, or the system will report an error

Parent and child components rely on the address of the application type to pass shared data

Unidirectional data flow

Prop is unidirectional: when a property of the parent component changes, it is passed to the child component, but not vice versa. This is to prevent the child component from inadvertently modifying the state of the parent component to prevent the data flow of the application from becoming difficult to understand.

<template id="father">
        <div class="father">
            <input type = "text" v-model = "message">
            <hr>
            <son :message = "message"></son>
        </div>
    </template>

    <template id = "son"> <div> <p> This is the child component </p> <inputtype = "text" v-model = "message"></input>
        </div>
    </template>
Copy the code

In addition, every time the parent component is updated, all prop of the child component is updated to the latest value. This means that you should not change prop inside child components. If you do, Vue will warn you on the console.

Therefore, if we want to realize data sharing between father and son, we should rely on address passing of application type. Message should be written in the form of an object, and the object should be passed to the child component when passing, and the child component uses the value of the object when referencing.

<template id="father">
        <div class="father">
            <input type = "text" v-model = "message.value"> <hr> <! <son :message = <son :message ="message"></son>
        </div>
    </template>

    <template id = "son"> <div> <p> This is the child component </p> <! -- use the value of the object when referencing --> <inputtype = "text" v-model = "message.value"></input>
        </div>
    </template>
Copy the code

When the value of the parent component is changed, the data of the child component is changed synchronously. When the child component changes the value of the parent component, the data of the parent component is also changed synchronously. This is because we operate on the same object whether it is a child component or a parent component. The parent component directly passes the address of the reference type to the child component. The child does not modify the object directly, but only changes the property values inside it.

Father that component if a reference type dynamic data is passed to the child components, data become two-way control, child components change data when the parent component can also receives the data changes, because the child components change when not in change data (address), but in the content of the change in the data, that is a reference type the address of the data has not change, not to change the parent component data.

Note: In JavaScript, objects and arrays are reference types, pointing to the same memory space. If prop is an object or array, changing it inside a child component will affect the state of the parent component. message:{val:””}

5, ViewModel relationship chain

A ref chain can be formed between components using a ref. Components also have a relationship chain ($parent) through both chains. In theory, any two components can access and communicate with each other.

$parent: parent component

$children: child component

$root: indicates the root component

When a child modifies the value passed by the parent in the set method, an error is reported because the child cannot modify the parent’s data.

Vue.component("bbb",{
        template:"#bbb",
        props:["msg"],
        computed:{
            /* ownMessage() {return this.msg;
            } */
            ownMessage:{
                get() {return this.msg;
                },
                set(val){this. MSG = val // Error: child cannot change data passed by parent}}}})Copy the code

Use $parent and let the parent change its own data

set(val){// this. MSG = val // console.log(this) // The parent component changed the MSG data this.$parent.msg = val;
                }
Copy the code

6. The parent component retrieves the child component’s data through the REF tag

The parent component is marked with ref when calling the child component

<template id="aaa">
        <div>
            <button @click = "get"</button> <! -- Not only can components be used$root/$parent/$childrenThe parent component can also actively mark the child component by ref --> < BBB ref ="b"></bbb>
        </div>
    </template>
Copy the code

The parent component has the $refs tag on its this property, which is used to fetch the child component

// Change the child component's data with the ref tag // this.$refs.b.message = "Ha ha"
Copy the code

Components can not only use $parent/children/root to obtain the corresponding component, the parent component can also actively mark the child component through ref, can also mark dom, can also form ref chain, and can also interact.

<button ref="btn" @click="get">get</button>
<bbb ref="b></bbb>  
Copy the code

Note that multiple subcomponents are marked with the same key name and should get an array

<bbb ref = "b" v-for = "(item,index) in 3" :key = "index"></bbb>
Copy the code

// Modify the corresponding value this with the subscript.$refs.b[0].message = "Ha ha"
Copy the code

Operation effect:

Child and parent components communicate

1. The child component changes the parent component’s data by using methods passed by the parent

A parent component can pass a method that changes its own data to a child component. When the child calls this method, it can pass data to the parent component, which passively receives data from the child component.

The child component declares its own MSG

Vue.component("son",{
        template:"#son", // The child component receives methods passed by the parent component."change"].data() {return{
                msg:"I am a child component"}}})Copy the code

The parent component starts with a piece of its own data

data() {returnParentMsg: parentMsg: parentMsg: parentMsg:""}}Copy the code

Write a method that changes its own data

Change (MSG){this.parentMsg = MSG}}Copy the code

Pass the written change method to the child component

<template id="father"> < div > < p > this is the parent component < / p > < p > subcomponents passed values are: {{parentMsg}} < / p > < hr > <! When calling a child component, pass the method that changes its own data to the child component --> <son :change ="change"></son>
        </div>
    </template>
Copy the code

The child component receives the change method passed by the parent component via props

props:["change"]
Copy the code

Add a click event to the P label, click on which will trigger the change method, and pass its MSG to the parent component, which is equivalent to the parent component’s change method being executed.

<template id="son"The > <div> <p> subcomponent says: {{MSG}}</p> < p@click ="change(msg)"</p> </div> </template>Copy the code

The parent component can render the data passed by the child component in the page

The <p> subcomponent passes the value {{parentMsg}}</p>Copy the code

Operation effect:

2. Realize parent-child communication through custom events

Each component or instance has a custom event, and the ability to trigger the event. The parent component binds a custom event to its child, and the event handler is a method of the parent component. When the child component fires the event, the parent component’s method is executed.

When a parent component wants to retrieve data from a child component, it binds the child component with a custom change-event event when calling the child component

<template id="father"> < div > < p > this is the parent component < / p > < p > subcomponents passed values are: {{parentMsg}} < / p > < hr > <! -- Bind a custom event to the child component --> < son@change-event ="change"></son>
        </div>
    </template>
Copy the code

Define a click event in the child component and click the P tag to execute the changeWord method

<p @click = "changeWord"> Click on the change method </p>Copy the code

$emit/changeWord/changeWord/changeWord/changeWord/changeWord/changeWord/changeWord/changeWord/changeWord/changeWord/changeWord

methods:{
            changeWord(){// Trigger the self-bound change event this.$emit("change-event"// The first argument is the name of the event that triggered the function, and the second argument is the value that was passed when the function was triggered}}Copy the code

Once a custom event bound to itself is triggered, the parent component’s change method is executed.

Sibling communication

1, through the viewModel relationship chain

Define the older component and add a click event to the older component that triggers the hitLittle method

<template id = "big-brother"> <div> <p> I am a brother </p> < button@click ="hitLittle"</button> </div> </template>Copy the code

Define the sibling component and add a P tag to the sibling component. Control its display and hiding with the Crying data

<template id="little-brother"> <div> <p> I am younger brother </p> <p v-if ="crying"</p> </div> </template>Copy the code

Declare crying data in the data of the sibling component. Default is false

Vue.component("little-brother",{
        template:"#little-brother".data() {return{
                crying:false}}})Copy the code

Define the hitLittle method in the methods of the elder component and change the crying method in the younger component via the viewModel relationship chain

 Vue.component("big-brother",{
        template:"#big-brother",
        methods:{
            hitLittle(){// In the communication between sibling components, can use the relation chain and ref chain to use, to solve the problem of communication between brothers. this.$parent.$children[1].crying = true; // littel changes its crying state}}})Copy the code

Operation effect:

2, ViewModel +ref chain

Add the REF tag to the younger component

<little-brother ref = "little"></little-brother>
Copy the code

Change the CRYING data in the brother component using the viewModel and ref chain in the hitLittle method of the brother component

hitLittle(){// In the communication between sibling components, can use the relation chain and ref chain to use, to solve the problem of communication between brothers. // this.$parent.$children[1].crying = true; // Littel changes its crying state // viewModel chain and ref chain use this together.$parent.$refs.little.crying = true;
            }
Copy the code

3. Eventbus

Create an empty instance

var angle = new Vue();
Copy the code

The sibling component defines a method to change its state

methods:{
            cry(){
                this.crying = true}}Copy the code

In the Mounted lifecycle function, bind a custom event. The first parameter is the name of the custom event, and the second parameter is the function to be handled

mounted(){// bind a custom event. The first argument is the name of the custom event, and the second function is the function Angle that needs to be handled.$on("hit-little",this.cry)
        }
Copy the code

Triggers a custom event in the elder component

hitLittle(){// Trigger the hit-little event Angle of the little-brother component.$emit("hit-little")}Copy the code

4. Vuex state management

Vuex is a global state management tool provided by VUE that deals with state sharing among multiple components in a project.

Vuex is an official vUE state management tool. What is state? We have a concept in front-end development: data-driven, any display difference on the page should be controlled by a piece of data, and this piece of data is also called state.

In vue. Data transfer and communication between components are frequent, and communication between parent and non-parent components is quite complete. However, the only difficulty is data sharing between multiple components, which is handled by VUEX

(1) Create a store

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)
Copy the code

(2) Set state

State is a pure object with some state mounted on it

state: {
    num:0,
    name:"list"
  }
Copy the code

(3) Configure store in the root instance

This way, we can use the store API in any component through this.$store

import store from './store/index'

Vue.config.productionTip = false

new Vue({
  router,
  store,
  render: h => h(App)
}).$mount('#app')
Copy the code

Use state in the Home component

computed:{ ... mapState({ num:state=>state.num }) },Copy the code

(5) Use mutations to change state

Mutations is also a pure object, which contains many methods to change state. The parameters of these methods receive state and change in the function body. In this case, the data used by the component will also change, realizing responsiveness.

mutations: {
    changeNum(state){
      state.num++
    }
  }
Copy the code

(6) Call the mutations method in the component to change the state in the component.

// Use mapMutations provided by Vuex to help us call the mutations method in the component... mapMutations(["changeNum"< button@click = < button@click ="changeNum"</button>Copy the code

Operation effect: