Getting avoid mutating a prop directly since the v

2020-04-12 16:03发布

I am new to vuejs and I am trying to sync active data to parent but getting an error as

vue.js:523 [Vue warn]: Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed property based on the prop's value. Prop being mutated: "active" (found in component )

My Vuejs Code is as below

<div id="app">
    <pre>
        {{$data}}
    </pre>
    <div v-for="plan in plans">
        <plan :plan="plan" :active.sync="active"></plan>
    </div>
</div>
<template id="mytemplate">
    <div>
        {{$data}}
        <span>{{plan.name}}</span>
        <span>{{plan.price}}</span>
        <button @click="setActivePlan">upgrade</button>
    </div>
</template>

<script src="vue.js"></script>
<script>
    new Vue({
        el: "#app",

        data: {
            active:this.active,
            plans: [
                {name: 'Diamond', price: '1000'},
                {name: 'Gold', price: '500'},
                {name: 'Silver', price: '250'},
                {name: 'Free', price: '0'}
            ]
        },
        components: {
            plan: {
                template: "#mytemplate",
                props: ['plan', 'active'],
                methods: {
                    setActivePlan: function () {
                        this.active = this.plan
                    }
                }
            }
        }

    });
</script>

Can any one help me to solve this

2条回答
男人必须洒脱
2楼-- · 2020-04-12 16:48

As the error suggests, you are trying to change one of the props active.

Prop being mutated: "active" (found in component )

As props are dynamically sent from parent, they will change whenever parent changes those, if you change them in child also, there will be conflict, thats why you are getting this error.

As par the documentation:

the parent-child component relationship can be summarized as props down, events up. The parent passes data down to the child via props, and the child sends messages to the parent via events.

So the proper way to do this will be to emit an event, which will call a method in parent and change the variable active in parent where it is defined. Following will be the code changes:

<script src="vue.js"></script>
<script>
    new Vue({
        el: "#app",

        data: {
            active:this.active,
            plans: [
                {name: 'Diamond', price: '1000'},
                {name: 'Gold', price: '500'},
                {name: 'Silver', price: '250'},
                {name: 'Free', price: '0'}
            ]
        },
        methods: {
           setActivePlan: function (plan) {
              this.active = plan
           }
        } 
        components: {
            plan: {
                template: "#mytemplate",
                props: ['plan', 'active'],
                methods: {
                    setActivePlan: function () {
                        this.$emit('setActivePlan', this.plan)
                    }
                }
            }
        }

    });
</script>
查看更多
萌系小妹纸
3楼-- · 2020-04-12 17:01

I hope this is the version problem. please show your VUEJS version, else get the version from below code.

<div id="app">
    <pre>
    {{$data |  json}}
    </pre>
        <div v-for="plan in plans">
            <plan :plan="plan" :active.sync="active"></plan>
        </div>
    </div>
    <template id="mytemplate">
        <div>
            <span>{{plan.name}}</span>
            <span>{{plan.price}}</span>
            <span>a{{plan.active}}</span>
            <button @click="setActivePlan">upgrade</button>
        </div>
    </template>

    <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/vue/1.0.25/vue.js"></script>
    <script>
        new Vue({
            el: "#app",

            data: {
                plans: [
                    {name: 'Diamond', price: '1000'},
                    {name: 'Gold', price: '500'},
                    {name: 'Silver', price: '250'},
                    {name: 'Free', price: '0'}
                ],
                active:{

                }
            },
            components: {
                plan: {
                    template: "#mytemplate",
                    props: ['plan', 'active'],
                    methods: {
                        setActivePlan: function () {
                            this.active = this.plan
                        }
                    }
                }
            }

        });
    </script>
查看更多
登录 后发表回答