Home > Mobile >  Vue2 Avoid mutating a prop directly since the value will be overwritten
Vue2 Avoid mutating a prop directly since the value will be overwritten

Time:11-02

I see this error when i want to pass a value who will be change after request response update it. It mean i have a modal child component that i want to close after the response has success and i have tyren something like this.

ERROR: [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: "addModalVisibility"

parent component

<v-action 
  @addUser="addUser" 
  :addModalVisibility="addModalVisibility"
></v-action>

 data(){
  return {
    addModalVisibility: false,
    ....

addUser(user_id, name, email, password){
                axios({
                    method: 'POST',
                    url: '/admin/users',
                    data: {
                        user_id: user_id,
                        name: name,
                        email: email,
                        password: password
                    }
                })
                .then(response => {
                    this.addModalVisibility = !this.addModalVisibility // i want to close the modal here 
                    this.getUsers()

child component

import Modal from './modal.js';
import Button from './button.js';

export default {
    components: {
        'v-modal' : Modal,
        'v-button': Button
    },

    data() {
        return {
            id: '',
            user_id: '',
            password: '',
            name: '',
            email: '',
            query: '',
            url: ''
        }
    },

    props: [
        'addModalVisibility'
    ],

    methods: {
        getUsers() {
            this.$emit('getUsers')
        },
    },

    template: `
        <div >
            <div >
                <div >
                    <!-- Button trigger modal -->
                    <v-button type="success" @click.prevent="addModalVisibility = !addModalVisibility" >
                        Add User
                    </v-button>
                    <v-button type="primary" data-mdb-toggle="collapse" data-mdb-target="#collapseFilter" aria-expanded="false" aria-controls="collapseFilter" >
                        Filter
                        <i ></i>
                    </v-button>
                    <v-button v-show="selected.length>0" type="danger"  id="dropdownMenuButton" data-mdb-toggle="dropdown" aria-expanded="false" >
                            Action ({{selected.length}})
                    </v-button>
                    <ul  aria-labelledby="dropdownMenuButton">
                        <li>
                            <a :href="url" >
                                Export
                                <i ></i>
                            </a>
                        </li>
                        <li>
                            <v-button @click="massDeleteUser()" type="danger" >
                                Delete
                                <i ></i>
                            </v-button>
                        </li>
                    </ul>
                </div>
                <div >
                    <input v-model="query" type="search"  placeholder="Search" />
                </div>
            </div>

            <!-- Add Modal -->
            <v-modal v-model="addModalVisibility" @submit_changers="addUser">
                <template v-slot:modalTitle>
                    Add User
                </template>
                <form id="" >
                    <div >                
                        <input v-model="user_id" id="user_id" type="number"  placeholder="user_id">        
                    </div>          
                    <div >                
                        <input v-model="name" id="name" type="text"  placeholder="name">        
                    </div>          
                    <div >                
                        <input v-model="email" id="email" type="email"  placeholder="email">        
                    </div>          
                    <div >                
                        <input v-model="password" id="password" type="password"  placeholder="password">        
                    </div>
                </form>
                <template v-slot:modalFooterBtn>
                    Save
                </template>
            </v-modal>
            
        </div>
    `,
}

CodePudding user response:

The error message you get states that the prop will be overwritten whenever the parent component re-renders. This is because updating the prop in the child component doesn't update it in the parent, so the parent will keep passing the same value to the child.

One way to get around this is to create a data property based on the prop's value. For example:

//child component

...
props: ['addModalVisibility'],
data(){
  return {
    ...
    modalVisibility: false
  }
},
mounted(){
  //here we move the value from our prop to a local data property
  this.modalVisibility = this.addModalVisibility;
}

Then in your child component you would use modalVisibility instead of addModalVisiblity - it's now in the app's data instead of in a prop.

  • Related