Home > OS >  How to pass dynamically props from one child component to another on the parent page
How to pass dynamically props from one child component to another on the parent page

Time:07-27

I have two child components I have to pass dynamically props from first child to parent and from parent to second child.

Parent

<script>
  data: () => ({
   model: {}
  }),
  methods: {
    changeData(payload) {
      this.model.personalData = {...payload}
    }  
  }
</script>
<template>
  <first-child @changeData="(payload) => changeData(payload)"/>
  <second-child :enter-object="model" />
</template>

Child one

<script>
  data: () => ({
   model: {}
  }),
  methods: {
    changeData() {
      this.$emit("changeData", this.model);
    }
  }
</script>
<template>
  <v-text-field v-model="model.name" @input="changeData()">
  <v-text-field v-model="model.email" @input="changeData()">
</template>

Child two

<script>
  props: {
    enterObject: {
      type: Object,
      required: false,
      default: () => ({})
    }
  },
  data: () => ({
    model: {}
  }),
  watch: {
    enterObject: {
      immediate: true,
      handler() {
        Object.assign(this.model.personalData, this.enterObject.personalData);
      }
  }
</script>
<template>
  <div>
    <div v-if="model.personalData.name || model.personalData.email">
      <span >{{ model.personalData.name }}</span>
      <span>{{ model.personalData.email }}</span>
    </div>
    <div v-else>
      No data
    </div>
  </div>
</template>

I get data in parent component with no problem, but this data doesn't pass to second child, why I have always "No data" ?

CodePudding user response:

You have to re-render the second child after invoking of changeData in parent for this you should add a key attribute in second-child component.

your Parent component should be like this:-

here is the working example

<template>
<div>
  <first-child @change-data="(payload) => changeData(payload)"/>
  <second-child :enter-object="model" :key="compKey"/>
</div>
</template>
<script>
import FirstChild from './FirstChild';
import SecondChild from './SecondChild';
export default {
  data: () => ({
   model: {},
   compKey: 0
  }),
  components: {
   FirstChild,
   SecondChild
  },
  methods: {
    changeData(payload) {
      this.model.personalData = {...payload};
      this.compKey  ;
    }  
  }
}
</script>

CodePudding user response:

I tested your code and found a few things:

You need to create "personalData" inside the model in "childTwo".

<template>
  <div>
    // I changed the validation for personalData
    <div v-if="model.personalData">
    <span >{{ model.personalData.name }}</span>
    <span>{{ model.personalData.email }}</span>
    </div>
  <div v-else>No data</div>
 </div>
</template>

export default {
  props: {
    enterObject: {
    type: Object,
    required: false,
    default: () => ({})
  }
},
data: () => ({
  model: {
    personalData: {}
  }
}),
watch: {
  enterObject: {
    deep: true,
    handler() {
    // Add a validation in the handler, you can use Object assign inside the validation.
      if(this.enterObject) {
        Object.assign(this.model.personalData, this.enterObject.personalData)
      }
    }
  }
}

It's worked for me.I hope it helps you.

  • Related