245 votes

Vue 2 - Mutation des accessoires vue-warn

J'ai commencé à https://laracasts.com/series/learning-vue-step-by-step de la série. Je me suis arrêté sur la leçon de Vue, Laravel, et AJAX avec cette erreur:

vue.js:2574 [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: "list" (found in component <task>)

J'ai ce code dans main.js

Vue.component('task', {
    template: '#task-template',
    props: ['list'],
    created() {
        this.list = JSON.parse(this.list);
    }
});
new Vue({
    el: '.container'
})

Je sais que le problème est créé() quand j'ai remplacer la liste prop, mais je suis un newbie en Vue, donc je suis totalement ne sais pas comment le résoudre. Quelqu'un a une idée de comment (et s'il vous plaît expliquer pourquoi) pour résoudre ce problème?

315voto

ira Points 1908

Cela a à voir avec le fait que la mutation d'un prop localement est considéré comme un anti-modèle en Vue 2

Ce que vous devez faire maintenant, dans le cas où vous souhaitez muter un accessoire localement, est de déclarer un champ dans votre data qui utilise l' props valeur que sa valeur initiale, puis muter la copie:

Vue.component('task', {
    template: '#task-template',
    props: ['list'],
    data: function () {
        return {
            mutableList: JSON.parse(this.list);
        }
    }
});

Vous pouvez en lire plus à ce sujet sur Vue.js guide officiel


Note 1: Veuillez noter que vous devez de ne pas utiliser le même nom pour votre prop et data, c'est à dire:

data: function () { return { list: JSON.parse(this.list) } // WRONG!!

Note 2: Car je sens qu'il y a une certaine confusion concernant l' props et de réactivité, je vous suggère de jeter un oeil sur ce thread

42voto

sealla Points 403

Vue vous avertit simplement: vous modifiez l'accessoire dans le composant, mais lorsque le composant parent sera restitué, "list" sera écrasé et vous perdrez toutes vos modifications. C'est donc dangereux de le faire.

Utilisez la propriété calculée instée comme ceci:

 Vue.component('task', {
    template: '#task-template',
    props: ['list'],
    computed: {
        listJson: function(){
            return JSON.parse(this.list);
        }
    }
});
 

24voto

For the Name Points 961

Si vous utilisez Lodash, vous pouvez cloner l'accessoire avant de le renvoyer. Ce modèle est utile si vous modifiez cet accessoire à la fois du parent et de l'enfant.

Disons que nous avons la liste des accessoires sur la grille des composants.

Dans la composante parent

 <grid :list.sync="list"></grid>
 

Dans la composante enfant

 props: ['list'],
methods:{
    doSomethingOnClick(entry){
        let modifiedList = _.clone(this.list)
        modifiedList = _.uniq(modifiedList) // Removes duplicates
        this.$emit('update:list', modifiedList)
    }
}
 

22voto

edison xue Points 413

Props down, événements en place. C'est le motif de Vue. Le fait est que si vous essayez de muter un accessoire en passant de parent. Cela ne fonctionnera pas et sera simplement écrasé de manière répétée par le composant parent. Le composant enfant ne peut émettre un événement que pour informer le composant parent de le faire. Si vous n'aimez pas ces restrictions, vous pouvez utiliser VUEX (en fait, ce modèle va aspirer dans la structure de composants complexes, vous devriez utiliser VUEX!)

17voto

Potato Running Points 106

Vous ne devez pas modifier la valeur des accessoires dans le composant enfant. Si vous avez vraiment besoin de le changer, vous pouvez utiliser .sync . Juste comme ça

<your-component :list.sync="list"></your-component>

 Vue.component('task', {
    template: '#task-template',
    props: ['list'],
    created() {
        this.$emit('update:list', JSON.parse(this.list))
    }
});
new Vue({
    el: '.container'
})
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X