1

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?

Taplar
  • 24,788
  • 4
  • 22
  • 35
Rubanraj Ravichandran
  • 1,213
  • 2
  • 17
  • 26

2 Answers2

1

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

  • But i am sending the data to props and storing it in a local data variable. And trying to change only the local data, but it updates the parent data too, I dont know how to restrict this!! – Rubanraj Ravichandran Mar 15 '18 at 15:15
  • 1
    All javascript objects are passed by `reference`, you're storing the `reference` in a local variable. If you want to make a NEW object you must clone it. –  Mar 15 '18 at 15:24
  • Thanks for your comment, you're right. It has been discussed more about here too. https://forum.vuejs.org/t/props-are-mutable-when-passed-as-an-object/2525/5 – Rubanraj Ravichandran Mar 15 '18 at 15:29
0

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.

Rubanraj Ravichandran
  • 1,213
  • 2
  • 17
  • 26