$выделяет объект родительскому компоненту и отправляет в массив. Объекты в массиве продолжают реагировать, почему?

#javascript #vue.js #vuejs2 #vuejs3

#javascript #vue.js #vuejs2 #vuejs3

Вопрос:

Я пытаюсь создать функцию, в которой пользователи могут добавлять несколько сообщений о возобновлении (из дочернего компонента) в массив (в родительском). Проблема в том, что каждый объект, который я отправляю в родительский массив, остается реактивным с дочерней формой / объектом. Итак, если я, например, очищу форму в дочернем компоненте, объект, который я отправил в родительский массив, также очистит все свои значения. Как мне передать и отправить post-объект в родительский массив и остановить его реактивный, чтобы я мог добавлять новые / дополнительные сообщения о возобновлении?

CreateProfile.vue

 <template>
    <ResumePostInput :resume_posts="form.resume_posts" @resumeHandler="handleResume"/>
</template>

<script>
export default {
    data() {
         form: {
              resume_posts: []
         }
    }
    methods: {
        handleResume(post) {
            this.form.resume_posts.push(post)
        }
    }
}
</script>
 

ResumePostInput.vue

 <template
-- Input fields binded to post object --
</template>

<script>  
export default {
    emits: ["resumeHandler"],
    props: {
         resume_posts: Array
    },
    data() {
        return {
            post: {
                title: '',
                sub_title: '',
                text: '',
                year_from: '',
                year_to: '',
                type: ''
            }
        }
    },
    methods: {
        addResume() {
            this.$emit("resumeHandler", this.post)
        }
    }
}
</script>
 

Комментарии:

1. Это vue 2 или 3? В вопросе не должно быть обоих тегов. Он не просто продолжает реагировать. Это тот же объект, он передается по ссылке. Если вы не хотите, чтобы это было затронуто в другом месте, создайте копию

2. vue3. Как мне сделать нереактивную копию? Если я сделаю что-то вроде let copy = this.post, а затем создам копию, она все равно будет реактивной

3. Смотрите это изображение giphy.com/gifs/8k0fixwuiQQBTt8hx5

Ответ №1:

вы выделяете неизвестное свойство, это a post , а не posts

и узнайте об объекте JS, есть копирование по ссылке и значению

может быть, вам просто нужно обновить свой метод addResume следующим образом

    addResume() {
      const post = JSON.parse(JSON.stringify(this.post))
      this.$emit("resumeHandler", post)
   }
 

Комментарии:

1. Да, я знаю, я неправильно набрал, когда писал этот пост. Предполагается, что это post. Но у меня проблема не в этом.

2. Да, JSON.parse / stringify сделали свое дело, спасибо! Я новичок в Javascript 🙂

Ответ №2:

Проблема не в том, что объект является реактивным, а в том, что это один и тот же объект, потому что объекты передаются по ссылке в JavaScript. Если он изменен в одном месте, он изменяется везде.

Чтобы избежать этого, объект должен быть явно скопирован. Для мелкого объекта это можно сделать с помощью распространения объекта:

 this.$emit("resumeHandler", {...this.post})
 

Для глубоко вложенных объектов можно использовать несколько расширений или стороннюю функцию клонирования.

Комментарии:

1. Спасибо. Понятия не имел об этом, но это работает 🙂