首页 > 解决方案 > 如何使用此和(多个)动态括号表示法更改 vue 数据变量

问题描述

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

  1. 我从包含数据变量“reportText.Scope_1_T_1”的 ap 元素开始,该变量包含字符串:“Text to change”;
  2. 在创建此组件时,created() 被调用并触发对方法 createObject 的调用。createObject 方法需要多个参数,但唯一相关的参数是第二个参数,其中包括我要更改的数据变量的位置(在本例中:“reportText.Scope_1_T_1”);
  3. createObject 方法根据点拆分此参数/位置并返回一个数组。所以字符串 "reportText.Scope_1_T_1" 返回数组 ["reportText", "Scope_1_T_1"];
  4. 之后这个数组被循环并与上下文(=this)结合。第一个循环返回 context = this["reportText"],第二个循环返回 context = this["reportText"]["Scope_1_T_1"]。
  5. 在此之后,我将一个新字符串分配给上下文(上下文 = 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"]),我将不胜感激。我认为这是解决这个问题的关键。

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

标签: javascriptvue.jsthis

解决方案


这只是最后一步是行不通的。最后分配一个新值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

所有漂亮且对称的c,de所有似乎都以相同的方式工作。

现在考虑翻转该示例:

b.c.d.e = a

这是非常不同的。

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

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

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

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


推荐阅读