在一个对象中嵌套计算属性以进行代码维护(Vue)

Nesting computed properties in one object for code maintenance (Vue)

就清洁逻辑和维护而言,以下场景的最佳实践是什么?

我的用例是有一个查询对象,它的参数是一堆text和前一个查询的结果

我最初想按如下方式构建代码(参见伪代码):

data() {
  return {
     queries : {
       q1 : { data: `${this.text} + ${this.formerResults}` }
       // q2, q3...
     },
     formerResults : ''
  }
},
methods : {
  makeQuery : function() {
    let vm = this;

    axios({ /* param of the query, data : this.queries.q1 */ })
     .then((response) => { vm.formerResults += /* add the results */ })
}

这个问题是 formerResults 确实被追加,但在下一个查询 q1 中注入时结果为 undefined。我不知道为什么,但通过将查询 q1 构造为计算 属性.

来解决问题

你能说出为什么在使用 属性 时逻辑会失败,而使用计算 属性 时逻辑会失败吗?

computed: {
   q1() {
      return {
          // same as above
      }
   }
   // q2, q3 ...
}

并在我的方法中调用它:

axios({ /* param of the query, data : this.q1 */ });

我可以看到参数textformerResults都被传递了。

但是,我想将查询(q1、q2、q3..)分组在同一个对象下 queries,就像在 data() 中一样:这是为了代码清晰,对于所有这些查询将针对相同的 url,我可能还有其他查询。

但正在努力:

computed: {
    computedQueries : {
       q1() {
          return {
          // same as above
        }
       },
       // q2, q3 ...
    }
}

并在我的方法中这样调用它:

axios({ /* param of the query, data : this.computedQueries.q1 */ })

会导致vue错误:

Error in v-on handler: "TypeError: Cannot read property 'q1' of undefined"

您能否阐明如何将计算属性分组(或嵌套)在一个对象中?

我真的需要在示例中使用计算的 属性 以避免 formerResults 在下一个查询中未定义吗?你能建议如何保持代码干净吗?

有几件事需要考虑。

第一个问题:你能说出为什么在使用 属性 时逻辑会失败,而使用计算 属性 时逻辑会失败吗?

data() 生命周期方法返回的属性在某种意义上是反应性的,每次您更改它们时,Vue 都会触发新的渲染周期。但这并不意味着每个反应 属性 都会自动更新。您仍然需要更新它。所以,当你这样做时:

data() {
  return {
    queries : {
      q1 : {
        data: `${this.text} + ${this.formerResults}` 
      }
    },

    formerResults : ''
  }
},

Vue.js 尚未将这些响应式属性添加到 this 实例。自然地,此时 this.formerResults 将是未定义的,而 this.queries.q1 会将其设为未定义。

为什么以及何时使用计算属性?

关于使用计算属性,你是对的。如果你需要自动建立依赖关系并且你不需要setter(即你自己设置值)一些属性,那么你必须使用计算属性.

在您的情况下,查询 - q1q2 等必须在 formerResults 更改时自动更新。为此,您将使用计算属性。

如何在一个对象中分组(或嵌套)计算属性?

您声明计算属性的方式有误,因此您看到了错误。 嵌套计算属性本身没有概念,但您可以创建一个单个复杂对象,它是多次计算的结果并生成单个包含您需要的所有数据的值:

computed: {
  queries: function () {
    return {
      q1: { data: `${this.text} + ${this.formerResults}`},
      q2: { /* Some other stuff */},
      //... q3, q4, etc.
    };
  }
}

每次 textformerResults 被代码的某些部分更改时,您的 queries 对象将被重新计算。不会有任何性能损失。

我真的需要在示例中使用计算的 属性 以避免 formerResults 在下一个查询中未定义吗?你能建议如何保持代码整洁吗?

使用计算 属性 是实现反应性的最干净的方法。在我看来,所有其他选择都很麻烦。例如,您可以使用 watchers 执行相同的操作,但它并不干净。

data() {
  return {
    queries: {
      q1: { data: '' },
      // q2, q3, ...
    },
    formerResults: ''
  }
},
watch: {
  formerResults: function() {
    this.queries = {
      q1: { data: `${this.text} + ${this.formerResults}` }
      // q2, q3, ...
    };
  },
  text: function() {
    this.queries = {
      q1: { data: `${this.text} + ${this.formerResults}` }
      // q2, q3, ...
    };
  }
}