The Vue parent component passes the value to the child component, and the child component modifies the data, and the parent component gets the latest value

Time:2020-11-5

In Vue projects, when components are nested, they often need to transfer values to each other. The following two methods are used:

  1. The parent component transmits values to the child component through attributes, and the child component receives data with props
<template>
    <div>
        <Child :myProp="data"></Child>
    </div>
</template>
<script>
import Child from "@/Child";
export default {
 components: {
    Child
  },
  data() {
    return {
      data: "123321"
    }
  }
};
</script>

Sub components:

<template>
    <div>
        <h1>{{myProp}}</h1>
    </div>
</template>
<script>
export default {
  data() {
    return {};
  },
  props:{
        myProp:{
          type:String,
          default:""
        }
    },
};
</script>

2. The child component sends the data inside the child component to the parent component through the $emit method, and takes the value to be passed as the second parameter of $emit, and the value will be passed to the method responding to the custom event as an argument

Parent component:

<template>
    <div>
        <Child @handle="myHandle"></Child>
    </div>
</template>
<script>
import Child from "@/Child";
export default {
 components: {
    Child
  },
  data() {
    return { }
  },
  method:{
    myHandle(str){
        console.log(str);//  => 123321
    }
  }
};
</script>

Sub components:

<template>
    <div>
        <h1>1112222</h1>
        <button @click='onclick'></button>
    </div>
</template>
<script>
export default {
  data() {
    return {};
  },
  method:{
    onclick(){
       this.$emit('handle','123321')
    }
  }
};
</script>

3. In addition, sibling components directly transfer values through bus, which is new Vue (). Since Vue does not have the method of directly transferring parameters through sub pairs, it is suggested that the sub components that need to transfer data should be merged into one component. If it is necessary to pass parameters from child to child, you can first pass it from the parent component to the child component. Or through eventbus or vuex (use eventbus for small projects and vuex for large projects).

4. And.syncIt’s just the grammar sugar of the above methods.

However, in the actual development process, I encountered a special scenario requirement. The parent component requests the interface and sends the initial data to the child component. After modifying the form in the child component, the submission operation is performed in the parent component. Moreover, the child component is switched through the tab, and the keep live package is usedv-bind:isswitch

After many attempts and explorations, we found a good solution,

Parent component:

<template>
        <el-tabs v-model="currentTab" :before-leave="tabBeforeLeave">
            <el-tab-pane v-for="(tab, $index) in tabs" :key="$index" :name="tab.alias">
                <span slot="label">
                    {{tab.name}}
                </span>
                <transition>
                    <keep-alive >
                        <component
                            v-bind:is="tab.relationComponent"
                            :ref="tab.relationComponent"
                            :data="data"
                        ></component>
                    </keep-alive>
                </transition>
            </el-tab-pane>
        </el-tabs>
</template>
<script>
import aComponent from "@/aComponent";
import bComponent from "@/bComponent";
import cComponent from "@/cComponent";
export default {
 components: {
        aComponent,
        bComponent,
        cComponent  
    },
  data() {
    return { 
        tabs:[ {
                    name: 'AAA',
                    alias: 'aaa',
                    relationComponent: 'aComponent',
                },{
                    name: 'BBB',
                    alias: 'bbb',
                    relationComponent: 'bComponent',
                },{
                    name: 'CCC',
                    alias: 'ccc',
                    relationComponent: 'cComponent',
                },],
                data:{
                    aChildData:{},
                    bChildData:{},
                    cChildData:{}
                }
    }
  },
 created() {
    this.getData()
    },
  method:{
   getData(){
//Data saved before interface request
  this.$api.funy({ id: '123457' },
                response => {
                  if(response){
                    this.data.aChildData=response;
                     this.currentTab = 'aaa';
                    this.$refs['aComponent'][0].localAssign();


                  }

                },
                fal => {
                
                }
            );

   },
   submit(){
   //The modified data in the component can be obtained through the following method and submitted in the parent component
         let achild = this.$refs['aComponent'][0].sogalocal
   
   
   }
  }
};
</script>

Subcomponent:

<template>
    <div>
  <el-form  v-model="sogalocal" label-width="120px">
        <el-input
                type="textarea"
                :autosize="{ minRows: 4, maxRows: 6}"
                placeholder="placeholder"
                maxlength="42"
                show-word-limit
                v-model="sogalocal.desc">
        </el-input>
        <el-radio-group v-model="sogalocal.bingAuth">
            < El radio label = "Jia" > Song Bingjia < / El radio >
            < El radio label = "Yi" > Song Bing B
            < El radio label = "Bing" > Song Bing C < / El radio >
        </el-radio-group>
        </el-form>
    </div>
</template>

<script>
    export default {
        name: 'child'
        props: {
            data:{
                type: Object,
                default: () => {},
            }
        },
        data() {
            return {
                sogalocal: null
            };
        },
        created() {},
        mounted(){},
        methods: {
            localAssign(){
            // wait until the parent component gets the data, then call this.$refs['aComponent'][0].localAssign (); implement data localization.
            //Or pass the data to localassign (achilddata) through this interface
                this.sogalocal = Object.assign({},this.data.aChildData)
            },
        }
    };
</script>

Recommended Today

Deeply analyze the principle and practice of RSA key

1、 Preface After experiencing many dark moments in life, when you read this article, you will regret and even be angry: why didn’t you write this article earlier?! Your darkest moments include: 1. Your project needs to be connected with the bank, and the other party needs you to provide an encryption certificate. You have […]