在一个对象中嵌套计算属性以进行代码维护 (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 确实被附加了,但在下一个查询 undefined 中注入时结果为 q1。我不知道为什么,但通过将查询 q1 构建为计算属性来解决了这个问题。

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

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

并在我的方法中调用它:

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

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

但是,我想在同一个对象 queries 下对查询 (q1,q2,q3..) 进行分组,就像在 data() 中一样:这是为了代码清晰,因为所有这些查询都将反对同一个网址,我可能还有其他网址。

但是尝试:

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,...
    };
  },text: function() {
    this.queries = {
      q1: { data: `${this.text} + ${this.formerResults}` }
      // q2,...
    };
  }
}

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...