如何使用这个和(多个)动态括号符号更改 vue 数据变量

How to change a vue data variable using this and (multiple) dynamic bracket notations

我正在努力实现以下目标:

  1. 我从包含数据变量 "reportText.Scope_1_T_1" 的 p 元素开始,此变量包含字符串:"Text to change";
  2. 创建此组件时,将调用 created() 并触发对方法 createObject 的调用。 createObject 方法需要多个参数,但唯一相关的参数是第二个参数,其中包括我要更改的数据变量的位置(在本例中:"reportText.Scope_1_T_1");
  3. 方法 createObject 根据点和 returns 数组拆分此 argument/location。所以字符串 "reportText.Scope_1_T_1" returns 数组 ["reportText", "Scope_1_T_1"];
  4. 接下来这个数组被循环遍历并与上下文结合(=this)。第一个循环导致 context = this["reportText"],第二个循环 returns in context = this["reportText"]["Scope_1_T_1"]。
  5. 在此之后,我将一个新字符串分配给上下文 (context = reply.fields)

我的预期是此代码会导致数据变量 this.reportText.Scope_1_T_1 发生变化,但不幸的是此变量没有发生任何变化。

我试过使用点符号和括号符号,但没有任何效果。例如,如果我尝试将 createObject 方法中的代码更改为:

突然有用了?我不明白为什么。我什至试图看看我是否以某种方式制作了 'this' 的副本,因此它不引用同一个对象,但据我所知它没有制作副本。它似乎确实是一个参考问题,因为当我使用我的动态括号时它以某种方式指向不同的位置。

这是我的相关代码(如果你需要更多,请告诉我):

<template>
  <p>{{ reportText.Scope_1_T_1 }}</p>
</template>

<script>
export default {
  data: function() {
    return {
      reportText: {
        Scope_1_T_1: 'Text to change'
      }
    }
  },
  created() {
    this.$store.getters.getAppPromise.then(app => {
      this.createObject(app, 'reportText.Scope_1_T_1', 'String', '=irrelevantExpression');
    })
  },
  methods: {
    createObject(app, location, type, expression) {
      if (type === 'String') {
        app.createGenericOjbect(
          {
            fields: {
              qStringExpression: expression
            }
          },
          reply => {
            let context = this;
            location = location.split('.');

            location.forEach(item => {
              context = context[item];
            });

            context = reply.fields;
          }
        )
      }
    }
  }
}
</script>

如果有人能帮我弄清楚使用动态创建的上下文和静态上下文之间的区别(例如:this["reportText"]["Scope_1_T_1"],我将不胜感激).我认为这是解决这个问题的关键。

我的代码基于这个 Whosebug 问题: Javascript Square Bracket Notation Multiple Dynamic Properties

只是最后一步不行。最后为 context 分配一个新值只会更新该局部变量,而不是对象的 属性。

相反,您需要做的是获取对相关对象的引用,然后更新 属性。要获取对象,您需要从 location 路径中删除最后一部分。最后一部分是需要更新的 属性 名称:

let context = this;
const path = location.split('.');
const property = path.pop()

path.forEach(item => {
  context = context[item];
});

context[property] = reply.fields;

用于 属性 访问的语法隐藏了路径各部分解释方式的一些不对称性。

考虑这个例子:

const a = b.c.d.e

发生的事情是:

  1. b 开始。
  2. 获取属性中的值c.
  3. 获取属性中的值d.
  4. 获取属性e中的值。
  5. 将该值分配给 a

一切都很好而且对称,cde 似乎都以相同的方式工作。

现在考虑翻转那个例子:

b.c.d.e = a

这是非常不同的。

  1. b 开始。
  2. 获取属性中的值c.
  3. 获取属性中的值d.
  4. a 分配给 属性 e

在这种情况下,cd 属性仍然只是读取操作,但 e 的处理方式完全不同。最后一部分是写入操作。

这里要注意的关键是,当您要设置值时,像这样的 'path' 的最后部分很特别。通常这隐藏在语法后面,但是当你想像在你的例子中那样分解它时,你需要意识到实际发生了什么。

无论您使用 . 还是 [] 表示法都不会影响此行为,但要动态访问属性,您必须使用 [].