web-dev-qa-db-fra.com

Comment résoudre [Vue avertir]: Éviter de muter directement un accessoire car la valeur sera écrasée sur vue.js 2?

Mon avis est comme ça:

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

Mon composant étoile est comme ça:

<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>

Mon css est comme ça:

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;
}

Lorsque je clique sur l'étoile, il existe une erreur sur la console comme ceci:

[Vue warn]: évitez de transformer directement un accessoire, car la valeur sera écrasée à chaque nouvelle restitution du composant parent. Utilisez plutôt une propriété data ou calculée en fonction de la valeur de l'accessoire. Prop en cours de mutation: "valeur" (trouvé dans C:\xampp\htdocs\myshop\ressources\assets\js\components\Star.vue)

Comment puis-je le résoudre?

4
samuel toh

Vous changez la propriété value ici.

return this.value = star;

Et peut-être ici.

v-model="value"

L'avertissement signifie que chaque fois que votre vue est restituée, la propriété value sera définie sur $data['rating'], ce qui écrasera tout ce que vous avez fait dans le composant de démarrage.

Au lieu de muter la propriété à l'intérieur de votre composant, lorsque quelqu'un clique sur une étoile, vous souhaiterez probablement $emit modifier le composant et laisser votre vue modifier $data['rating'], ce qui rendra à nouveau le composant étoile correctement.

Voir la documentation de Vue concernant composition du composant

3
Bert

Vous devez faire le calcul avec un getter et un setter, puis utiliser $emit pour mettre à jour le prop, par exemple:

    computed: {
        starValue:{ 
            get:function () {
                return this.temp_value
            },
            set: function(newValue){
                // $emit is the correct way to update props:
                this.$emit('update:value', newValue);
            }
        }
    }
2
Andy

L'avertissement suggère de ne pas modifier directement la valeur d'un accessoire car vous perdriez de toute façon le changement si les données du composant parent étaient modifiées.

Ceci dit, ici dans votre méthode:

methods: {
  rate: function (star) {
    var self = this;
    if (!this.disabled) {
        this.$http.post(window.BaseUrl + '/star', {star: star}).then(function (response) {
            console.log('submitted');
        });
        this.temp_value = star;
        // return this.value = star; - remove this line
    }
  }
}

et ajoutez une propriété calculée comme ceci:

computed: {
  starValue () {
    return this.temp_value
  }
}
0
Amresh Venugopal