Automatically mutating parent component in Vue

Viewed 34

While changing a $data object form_data, automatically changes to paren prop!

#Blade page:

<job-listing
        :employer_question_format="{{ json_encode($employer_question_format) }}"
    ></job-listing>

#Parent compomnent:

props: [
        'employer_question_format',
    ]

#Pass to child component

<job-listing-employer-questions
                        :employer_question_formats="employer_question_format"
                    ></job-listing-employer-questions>

#Child component

<button type="button" @click="addMoreQuestion('short')" class=" ic-add-input">
                                                    <i class="ri-add-circle-line plus-icon"></i>
                                                </button>

export default {
    name: "JobListingEmployerQuestions",
    props: [
        'employer_question_formats'
    ],
    data() {
        return {
            selectedType: 'short',
            form_data: {
                employer_questions: []
            }
        }
    },
    mounted() {
        this.form_data.employer_questions = this.employer_question_formats
    },
    methods: {
        validate(){
            this.$emit('on-validate', this.$data, true)
            return true;
        },
        addMoreQuestion(type){
            let qqq = {"id":"q1","type":"short","question":"","is_required":false,"is_knockout":false,"knockout_answer":"","data_upload_by":"","user_data":""}
            this.form_data.employer_questions.push(qqq)
        }
    },
}

When I add or change anything in form_data.employer_questions , it also changes to parent component and child component prop. Please check my screenshots: By default there are 3 objects. When I add or change it also affect all over there

  1. Child component - https://prnt.sc/zPvIHefmY9EX
  2. Parent component - https://prnt.sc/qyqmacMquYuE

Why is it happening and how to do it correctly?

1 Answers

When you assign one array to another you are passing the first array's reference value, meaning changes to one will affect the other. To prevent this you can create a shallow copy of the array during assignment. There are multiple ways to do this:

spread syntax (ES6)

this.form_data.employer_questions = [...this.employer_question_formats]

Array.from()

this.form_data.employer_questions = Array.from(this.employer_question_formats)

Array.prototype.slice()

this.form_data.employer_questions = this.employer_question_formats.slice()
Related