简体   繁体   中英

How to modify value in child Vue component

I'm trying to wrap my wits around the semantics of Vue props and data properties. In the code below, the item child component accepts newItem from the parent. The child component defines item (sorry for the ambiguity) as this.newItem . The parent passes in newItem instead of item in order to get around the prohibition of modifying parent component values directly.

The console shows no warnings, but I'm wondering if only because the Vue rendering(?) machinery doesn't recognize a violation. The child item can be seen in dev tools to be simply creating a reference to the passed-in newItem , so in essence the prop is still getting modified directly.

Should I be initializing the child item using the Item constructor, instead? Or must the child instead issue some kind of 'cancel-edit` event which is handled by the parent?

cancelEdit assigns _cachedItem to item , which is the same(?) as assigning to newItem :

// An item
Vue.component('item', {
    props: [
      'newItem'
    ],
    data: function() {
      return {
        item: this.newItem,
        editing: false,
        _cachedItem: null
      }
    },
    methods: {
      startEdit: function() {
        debugger
        this._cachedItem = new Item(this.item.id, this.item.text);
        this.editing = true;
      },
      cancelEdit: function() {
        debugger
        this.item = this._cachedItem;
        this._cachedItem = null;
        this.editing = false;
      },
      finishEdit: function() {
        debugger
        this.editing = false;
      },
    },
...

Parent template:

Vue.component('items', {
    props: {
      'items': {
        type: Array,
      },
      'item-type': {
      type: String
    }
    ...
        <item
            v-for="(item, index) in items"
            v-bind:newItem="item"
            v-bind:key="item.id"
            v-on:remove="removeItem(index)" />
    ...

In JavaScript objects are passed by reference. The Vue docs clearly state ..

Note that objects and arrays in JavaScript are passed by reference, so if the prop is an array or object, mutating the object or array itself inside the child component will affect parent state.

If you'd like to avoid this behavior you can create deep clones of your objects. Something like this ..

item: JSON.parse(JSON.stringify(this.newItem)),

Which would create a completely independent local copy of your object. If you'd like to keep both objects in sync then you can communicate your intent to mutate a value to the parent through events and have it update it's own copy of an object. An elegant way to handle this would be by using the .sync modifier .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM