【问题标题】:Accidentally updating child variables意外更新子变量
【发布时间】:2020-10-28 00:57:21
【问题描述】:

我目前正在处理包含父/子组件的页面。当我在父组件中管理其变量时,我的子组件会以某种方式得到更新。 我正在尝试做的事情:

  1. 我的子组件有一个“站点”变量,其中包含我需要通过 API 发送的所有数据
  2. 我的父组件有一个保存按钮,用于将子数据发送到后端
  3. 当子组件中的“站点”发生变化时,我会向父组件发送一个事件 @change
  4. @change 事件包含我需要的所有数据,但不是我想要的格式
  5. 有一个函数 submit() 可以获取此数据并修改其中一个数组,以便: ['foo','bar'] 变为此 'foo,bar'
  6. 问题当我执行步骤“5”时,我的子组件会更新

父组件内的子组件

<configuracoes :configuracoes="configuracoes" @change="setData"
      v-if="currentPage === 'configs'"/>

子组件发出的change事件

this.$emit("change", this.site);

'site' var 的重要部分

site: {
  seo: {
   keywords: [],
             ...
           },
          ...
    },

setData() 函数

setData(data) {
    this.data = data;
},

submitData() 函数

submitData() {
    if (this.currentPage === "configs") {

        let data = ({}, Object.assign(this.data))
        let keywords = data.seo.keywords.join(',')
        data.seo.keywords = keywords
        this.$store.dispatch("sites/updateSite", {
            empresa_id: this.user.empresa_id,
            site_id: this.siteId,
            dados: data,
        });
    }
}

如您所见,我声明了另一个变量 let data 以避免更新 this.site 变量,但没有成功

【问题讨论】:

  • data.seo.keywords = keywords 可能是孩子数据变化的原因
  • 顺便问一下,你为什么需要这个逗号表达式? let data = ({}, Object.assign(this.data))
  • @hlfrmn 我试图在不更改站点变量的情况下修改数据变量,但我做错了

标签: javascript vue.js vue-component dom-events


【解决方案1】:

首先,您“复制”this.data 对象的方式存在问题。

let data = ({}, Object.assign(this.data)); // this doesn't work
console.log(data === this.data); // true

const dataCopy = Object.assign({}, this.data); // this works
console.log(dataCopy === this.data); // false

Object.assign 的工作方式,所有属性都将被复制到第一个参数中。由于您只传递了一个参数,因此它不会改变并且仍然指向同一个旧对象。


如果您使用正确的方法,您很可能仍会遇到同样的问题。原因是data.seo 不是原始值(数字或字符串),而是一个对象。

这意味着整个seo 对象将被复制到新副本中。换句话说,即使dataCopy !== this.datadataCopy.seo === this.data.seo。这称为“浅拷贝”。

您要确保不修改原始 seo 对象,这里有一些方法可以做到这一点。

let goodCopy;
const newKeywords = this.data.seo.keywords.join(',');

// use object spread syntax
goodCopy = {
    ...this.data,
    seo: {
        ...this.data.seo,
        keywords: newKeywords,
    },
};

// use Object.assign
goodCopy = Object.assign(
    {},
    this.data,
    {
        seo: Object.assign(
            {},
            this.data.seo,
            {keywords: newKeywords}),
    });

// create a copy of "seo", and then change it to your liking
const seoCopy = {...this.data.seo};
seoCopy.keywords = newKeywords;
goodCopy = Object.assign({}, this.data, {seo: seoCopy});

this.$store.dispatch('sites/updateSite', {
    empresa_id: this.user.empresa_id,
    site_id: this.siteId,
    dados: goodCopy,
});

如果您想了解复制 JavaScript 对象的方法,here's a good question

【讨论】:

  • 感谢您的回答。昨天我正在寻找修复并发现对象和引用是如何工作的。尽管做了这么久的程序员,但还有很多东西要学(我不能投票,因为我没有足够的声誉)
猜你喜欢
  • 1970-01-01
  • 2021-10-17
  • 2014-10-21
  • 2013-11-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多