$emit 对象到父组件,并推送到数组。数组中的对象仍然是反应性的,为啥?

Posted

技术标签:

【中文标题】$emit 对象到父组件,并推送到数组。数组中的对象仍然是反应性的,为啥?【英文标题】:$emit object to parent component, and push to array. Objects in array continue to be reactive, why?$emit 对象到父组件,并推送到数组。数组中的对象仍然是反应性的,为什么? 【发布时间】:2022-01-14 11:10:57 【问题描述】:

我正在尝试创建一个功能,用户可以将多个简历帖子(从子组件)添加到数组(在父组件中)。 问题是,我推送到父数组的每个对象都与子表单/对象保持反应。因此,例如,如果我清除子组件中的表单,我推送到父数组的对象也会清除它的所有值。如何发出 post-object 并将其推送到父数组并阻止它反应,以便我可以添加新的/更多的简历帖子?

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>

【问题讨论】:

这是 vue 2 还是 3?这个问题不应该有两个标签。它不仅继续是被动的。它是同一个对象,它是通过引用传递的。如果您不希望它在其他地方受到影响,请创建一个副本 vue3.如何制作非反应性副本?如果我执行 let copy = this.post 之类的操作,然后发出副本,它仍然是响应式的 看这张图片giphy.com/gifs/8k0fixwuiQQBTt8hx5 【参考方案1】:

您发出未知属性,它是post,而不是posts

了解JS对象,还有copy by reference & value

也许你只需要像这样更新你的 addResume 方法

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

【讨论】:

是的,我知道,我写这篇文章的时候打错了。应该是发帖了但这不是我遇到的问题。 是的,JSON.parse/stringify 成功了,谢谢!我是 javascript 新手 :)【参考方案2】:

问题不是对象是响应式的,而是它是同一个对象,因为对象在 JavaScript 中是通过引用传递的。一处修改,处处修改。

为了避免这种情况,需要显式复制对象。对于浅层对象,这可以通过对象传播来完成:

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

对于嵌套较深的对象,可以使用多重传播或第三方克隆功能。

【讨论】:

谢谢。不知道这个,但它有效:)

以上是关于$emit 对象到父组件,并推送到数组。数组中的对象仍然是反应性的,为啥?的主要内容,如果未能解决你的问题,请参考以下文章

如何设置状态并推送到数组?

如何在 Vue 中求和并推送到匹配的对象

匹配字谜并推送到数组

(十三)Vue3.x中的emits选项

将数组添加到父组件的状态

将 vue.js 组件子中的对象或值发送到父通信