VueJS error Avoid mutating a prop directly

大憨熊 提交于 2021-02-18 21:53:09

问题


I'm trying to create a modal but I'm getting this error only when I close it:

[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

---> <PanelDesconectarModal> at resources\assets\vue\PanelDesconectarModal.vue
       <VNavigationDrawer>
         <PanelDrawer> at resources\assets\vue\PanelDrawer.vue
           <VApp>
             <PanelRoot> at resources\assets\vue\PanelRoot.vue
               <VApp>
                 <Root>

PanelDesconectarModal.vue

<template>
    <v-dialog v-model="value" max-width="350">
        <v-card :dark="($theme === 'dark')">
            <v-card-title class="headline">Desconectar</v-card-title>
            <v-divider></v-divider>
            <v-card-text>Você tem certeza que deseja desconectar-se?</v-card-text>
            <v-card-actions>
                <v-spacer></v-spacer>
                <v-btn flat @click.native="closeDialog">Cancelar</v-btn>
                <v-btn :color="$color" flat="flat" @click.native="desconectar">Desconectar</v-btn>
            </v-card-actions>
        </v-card>
    </v-dialog>
</template>

<script>
    export default {
        name: 'panel-desconectar-modal',
        props: ['value'],
        methods: {
            closeDialog() {
                this.value = false;
            },
            desconectar() {
                this.closeDialog();

                window.location = this.$route + '/panel/desconectar';
            }
        }
    }
</script>

Using ProgressDesconectarModal.vue, showDesconectar is a data variable

<panel-desconectar-modal :value="showDesconectar"></panel-desconectar-modal>

回答1:


This happens because you have props value in your v-model.

Do not do that, as that will mutate the prop(value) when v-model changes (you should only change data values with v-model afaik, but in this case, you don't even need additional data variable).

Since vuejs v2.3.0, it is suggested to emit value to the parent, so that parent changes it, and it is then passed to child component.


So all you have to do is:

in v-dialog component

remove v-model and replace it with :value="value" @input="$emit('input')"

And your function:

closeDialog() {
    this.$emit('input');
}

In panel-desconectar-modal component use v-model="showDesconectar".


This will work because:

<input v-model="something"> is syntactic sugar for:

<input   
    v-bind:value="something"
    v-on:input="something = $event.target.value">

Here is working example pen which I provided in an answer to similar question.




回答2:


This is really the moment to ask yourself "Do I really need a prop? Can I do this with data? Am I here because I mistakenly put some state in Vue component?"

If you're the author of the page and the component, and the component only appears once on the page, there is no good reason to use props. If you need props because the component is repeated for all the lines in an array, make the prop just the array index, so the component can directly modify the source array in the store. Vue components should not contain state, especially state that needs to be shared, and do not enjoy being tightly bound to each other. The parent-child relationship arises out of the chance of their placement in the DOM tree, (children occur inside the markup of parents). This is like a chance meeting in a nightclub. The child may have nothing else to do with the parent. The hierarchy of your source data should be expressed, independently of your markup, in the structure of your store. Your Vue components, where possible, should have an intimate two way relationship with the store, and not talk much to each other :-)




回答3:


You should not mutate the props in your child component. You can only mutate the object but not primitives. So, you can use data option or a computed property:

data() {
  return {
    childValue: this.value; // initialize props value
  }
}

Now, you can change the childValue:

closeDialog() {
   this.childValue = false;
},

Make sure to use childValue everywhere inside your child component instead of value props.




回答4:


In the relevant Vue doc they don't have examples with default values, so these answers are to be found elsewhere. I needed a solution to create a component with a default value, but the input would always spring back to what it was before when it loses focus, or it gave the "avoid mutating a prop directly" error. Creating a mutable property and setting its value in the created event solved it for me:

data()
{
    return {
        text: null
    };
},

props: {
    properties: Object,
    value: String
},

created()
{
    this.text = this.value;
}


来源:https://stackoverflow.com/questions/49315487/vuejs-error-avoid-mutating-a-prop-directly

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!