Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to solve [Vue warn]: Avoid mutating a prop directly since the value will be overwritten on vue.js 2?

My view is like this :

<div class="col-md-8">
    ...
        <star :value="{{ $data['rating'] }}"></star>
    ...
</div>

My star component is like this :

<template>
    <span class="rating" :class='{"disable-all-rating": !!value}'>
        <template v-for="item in items">
            <label class="radio-inline input-star" :class="{'is-selected': ((starValue>= item.value) && starValue!= null)}">
                <input type="radio" class="input-rating" v-model="starValue" @click="rate(item.value)">
            </label>
        </template>
    </span>
</template>
<script>
    export default{
        props: {
            'value': null
        },
        computed: {
            starValue () {
                return this.temp_value
            }
        },
        data(){
            return{
                items: [
                    {value: 5},
                    {value: 4},
                    {value: 3},
                    {value: 2},
                    {value: 1}
                ],
                temp_value: null,
            }
        },
        methods:{
            rate: function (star) {           
               this.$http.post(window.BaseUrl + '/star', {star: star});                         
               this.temp_value = star;                         
            },
        }
    }
</script>

My css is like this :

span.rating {
  direction: rtl;
  display: inline-block;
}

span.rating .input-star {
  background: url("../img/star.png") 0 -16px;
  padding-left: 0;
  margin-left: 0;
  width: 16px;
  height: 16px;
}

span.rating .input-star:hover, span.rating .input-star:hover ~ .input-star {
  background-position: 0 0;
}

span.rating .is-selected{
   background-position: 0 0;
}

span.rating .is-disabled{
   cursor: default;
}

span.rating .input-star .input-rating {
  display: none;
}

When I click the star, there exist error on the console like this :

[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: "value" (found in at C:\xampp\htdocs\myshop\resources\assets\js\components\Star.vue)

How can I solve it?

like image 521
samuel toh Avatar asked Mar 01 '17 02:03

samuel toh


People also ask

Can we mutate props in Vue?

Mutating props in Vue is an anti-patternYes, in Vue, mutating props like this is considered to be an anti-pattern. Meaning — please don't do it, or you'll cause a lot of headaches for yourself. Why an anti-pattern? In Vue, we pass data down the the component tree using props.

How do you handle props in Vue?

To specify the type of prop you want to use in Vue, you will use an object instead of an array. You'll use the name of the property as the key of each property, and the type as the value. If the type of the data passed does not match the prop type, Vue sends an alert (in development mode) in the console with a warning.


1 Answers

You need to make the computed with a getter and a setter and then use $emit to update the prop e.g:

    computed: {
        starValue:{ 
            get:function () {
                return this.temp_value
            },
            set: function(newValue){
                // $emit is the correct way to update props:
                this.$emit('update:value', newValue);
            }
        }
    }
like image 94
Andy Avatar answered Nov 05 '22 04:11

Andy