Updating parent data via child component?

2019-09-06 09:38发布

What is correct procedure to update parent data via child component?

In the child component - I am modifying parent data directly via props. I am not sure if this is wrong way to go about it.

According to the vue doc:

when the parent property updates, it will flow down to the child, but not the other way around.

Example child component :

<script>
    export default {

        props: ['user'],

        data: function () {
            return {
                linkName: '',
                linkValue: '',
            }
        },

        methods: {
            addLink: function (event) {
                event.preventDefault();
                this.$http.post('/user/link', {name: this.linkName, key: this.linkValue}).then(response => {
                    this.user.links.push(response.data);
                }, response => {
                      // Error
                    }
                });
            },
        }
    }
</script>

I have used this.user.links.push(response.data); which modify the data directly to the parent component via props: ['user']

1条回答
三岁会撩人
2楼-- · 2019-09-06 10:08

As you rightly said, the props is not meant to pass data from child to parent. The data binding is one-way only.

The correct procedure is for child component to send an event via $emit to the parent component, along with some value (optional).

In your case, you may do the following in the addLink method of child component:

this.$http.post('/user/link', {name: this.linkName, key: this.linkValue}).then(response => {
    this.$emit("update-user-links", response.data);  // Send an event to parent, with data
}, response => {
    // Error
});

And your parent can listen to it as follows:

<my-user-link-component :user="userData" v-on:update-user-links="addUserLink"></my-user-link-component>

or the short-hand syntax:

<my-user-link-component :user="userData" @update-user-links="addUserLink"></my-user-link-component>

In the above, you are assigning a method addUserLink to handle the child component's event. In your parent component, you need to define this method as follows:

methods: {
    // ... your other methods,
    addUserLink: function(linkData) {
        this.userData.links.push(linkData);
    }
}

Benefits of this one-way binding from top to bottom and the event mechanism:

  • Your parent component can choose to ignore events if it wants - thus making child components reusable in other contexts.
  • Your child components (assuming you have many) will be allowed to send only events upwards, which is easier to debug when compared to each of them directly mutating parent state.
查看更多
登录 后发表回答