1
votes

This is my root element, and in the data "booking" is a object with sitebooking. Sitebooking object can have array of objects with first name and last name.

var app = new Vue({
    el: '#app',
    data: {
        booking: {
            sitebooking: [{
                firstname: "",
                lastname: ""
            },{
                firstname: "",
                lastname: ""
            }],
        }
    }
});

And this is my template (child component),

<template id="sitebooking_template">
    <div>
        <div class="row clearfix">
            <div class="col-md-6">
                <div class="form-group required">
                    <label for="firstname">First name</label>
                    <input class="form-control" placeholder="First name" required="" name="firstname" type="text" value="" id="firstname" v-model="newcompsitebooking.firstname">
                </div>

            </div>
            <div class="col-md-6">
                <div class="form-group required">
                    <label for="lastname">Last name</label>
                    <input class="form-control" placeholder="Last name" required="" name="lastname" type="text" value="" id="lastname" v-model="newcompsitebooking.lastname">
                </div>
            </div>
        </div>
    </div>
</template>

And i am looping through booking.sitebooking object in parent compoent to create multiple child component (each site booking will get one child component).

<div class="" id="app">
    <sitebooking v-for="(val,idx) in booking.sitebooking" :key="idx" :my-sb="val"></sitebooking>
</div>

I am passing the value through "my-sb" props and assinging in to local data in the child component.

Vue.component('sitebooking', {
  template: '#sitebooking_template',
  props:["mySb"],
  data: function () {
      return {
          newcompsitebooking : this.mySb,
      }
  }
});

Till now everything works, but the strange behavior is whenever I change the value in the child component, it updates the data of parent component too. But according to vuejs documentation, the change in child component will be propagated back to parent via emit. But i am not emitting data back to parent, but still the value updates automatically in parent.

Can anyone pls help on this?

2

2 Answers

1
votes

You're passing a pointer to the siteBooking object. The child object can do anything which that pointer it likes and the parent wont react, but the object and its properties are still shared.

EDIT Cloning an object to make a new one is called deep cloning

0
votes

I resolved this issue with the following changes.

Whenever I try to pass object as props and assigning into local variable in child, it actually copies the reference of the parent data, which leads to the problem. So if you do this, changes in child will affect the parent data which is not good.

I found a good discussion here,

https://forum.vuejs.org/t/props-are-mutable-when-passed-as-an-object/2525/5

Solution

To solve this issue, as suggested in @icecream_hobbit answer i tried to clone the prob obj and then store the new copy of it in the local data.

How to do clone object

Vuejs : How to pass an object as prop and have the component update sub-objects

Is this a good way to clone an object in ES6?

I modified my code like this now,

Vue.component('sitebooking', {
  template: '#sitebooking_template',
  props:["mySb"],
  data: function () {
      return {
          newcompsitebooking : {...this.mySb},
      }
  }
});

Now the issue solved. Thanks to @icecream_hobbit.