Fajar's avatar
Level 2

[Vue warn]: Avoid mutating a prop

hay, I'm trying to make a subscribe button when I click the subscribe button I get a message colored mutated

but the data is entered into a table like this message I got

[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

---> at resources/js/components/SubscribeButton.vue at resources/js/pages/Thread.vue

SubscribeButton.vue

<button :class="classes" @click="subscribe">Subscribes</button>

export default { props: ['active'],
    computed: {
       
        classes() {
            
            return ['btn', this.active ? 'btn-primary' : 'btn-secondary'];
            

        }

    },

    
    methods: {

        
        subscribe() {
            
            
            axios[
                
                (this.active ? 'delete' : 'post')
            ](location.pathname + '/subscriptions');
            
            this.active = ! this.active;

            flash('Subscribe');

        }

    }

}

disscusionHeader.blade.php

<subscribe-button :active="{{ json_encode($thread->isSubscribedTo) }}"></subscribe-button>

can you help me

0 likes
7 replies
D9705996's avatar

You are passing the active data as a prop and as the error message states you should not mutate/modify props.

You can create a data property that is set to the prop value

data: function () {
  return {
    button: {
      active: this.active
    }
  }
}

Then anywhere you reference this.active change to this.button.active

computed: {
        classes() {
            return ['btn', this.button.active ? 'btn-primary' : 'btn-secondary'];
        }
    },

https://vuejs.org/v2/guide/components-props.html#One-Way-Data-Flow

usaandi's avatar

did you register your data prop active?

 export default {
        props:['active'],
        name: "Component",
        data(){
            return{
                isActive: this.active,
            }

        },

        methods:{
          
        }
    }

and then use this.isActive variable

Fajar's avatar
Level 2

hy @D9705996 if I make it like this the class button doesn't change every time I click

<button :class="classes" @click="subscribe">Subscribes</button>

data: function () { return { classes: { active: 'btn'? 'btn-primary' : 'btn-secondary', } } }

<subscribe-button :active="{{ json_encode($thread->isSubscribedTo) }}"></subscribe-button>

Fajar's avatar
Level 2

@usaandi I might use it on Thread.vue

Thread.vue

import Replies from '../components/Replies.vue'; import SubscribeButton from '../components/SubscribeButton.vue';

export default {

    props: ['initialRepliesCount'],

    components: { Replies,SubscribeButton },

    data() {

        return {

            repliesCount: this.initialRepliesCount

        };

    }

}
D9705996's avatar

you need to change all reference to this.active to this.button.active#

subscribe() {
   axios[(this.active ? 'delete' : 'post'](location.pathname + '/subscriptions').then(funtion() {
     this.button.active = !this.button.active;
     flash('Subscribe');
   })
}

I hve added a .then function so the active is only changed once the axios request completes.

Fajar's avatar
Level 2

@D9705996 first

i add <subscribe-button :active="{{ json_encode($thread->isSubscribedTo) }}"></subscribe-button>

in _disscusionHeader.blade.php

  1. i create SubscribeButton.vue

<button :class="classes" @click="subscribe">Subscribes</button>

export default { props: ['active'],
    computed: {
       
        classes() {
            
            return ['btn', this.active ? 'btn-primary' : 'btn-secondary'];
            

        }

    },

    
    methods: {

        
        subscribe() {
            
            
            axios[(this.active ? 'delete' : 'post')]
            (location.pathname + '/subscriptions');
            
            this.active = ! this.active;

            flash('Subscribe');

        }

    }

}
  1. i use Thread.vue to register the SubscribeButton in _disscusionHeader
import Replies from '../components/Replies.vue';
import SubscribeButton from '../components/SubscribeButton.vue';

export default {

    props: ['initialRepliesCount'],

    components: { Replies,SubscribeButton },

    data() {

        return {

            repliesCount: this.initialRepliesCount

        };

    }

}
D9705996's avatar

@fajar - you have not made any of the changes I mentioned in the code above. If you want the warning to stop you need to stop changing the value of this.active as it is a prop. e.g. this code will change the prop.

this.active = ! this.active;

If you need help getting the basics of VueJS sorted then check out this series

https://laracasts.com/series/learn-vue-2-step-by-step

Please or to participate in this conversation.