Вложение вычисленных свойств в один объект для обслуживания кода (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 */ });

Я вижу, что оба параметра text и formerResults переданы.

Однако я хотел бы сгруппировать запросы (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 не было неопределенным в следующем запросе? Вы можете посоветовать, как содержать код в чистоте?


person user305883    schedule 26.04.2021    source источник


Ответы (1)


Есть несколько вещей, которые следует учитывать.

Первый вопрос: можете ли вы сказать, почему логика не работает при использовании свойства и работает с вычисляемым свойством?

Свойства, возвращаемые методом жизненного цикла data(), являются реактивными в том смысле, что каждый раз, когда вы их изменяете, новый цикл рендеринга запускается Vue. Но это не означает, что каждое реактивное свойство будет обновляться автоматически. Вам все равно придется его обновить. Итак, когда вы это делаете:

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

    formerResults : ''
  }
},

Vue.js еще не добавил эти реактивные свойства в экземпляр this. Естественно, что this.formerResults на этом этапе будет неопределенным, а this.queries.q1 получит его как неопределенное.

Почему и когда использовать вычисляемые свойства?

Вы правы в использовании вычисляемых свойств. Если вам нужно установить отношения зависимости автоматически, и если вам не нужен установщик (то есть для самостоятельной установки значений) для некоторого свойства, тогда вы должны использовать вычисляемое свойство.

В вашем случае запросы - q1, q2 и т. Д. Должны автоматически обновляться при изменении formerResults. Для этого вы будете использовать вычисляемые свойства.

Как я могу сгруппировать (или вложить) вычисленные свойства в один объект?

Ваш способ объявления вычисляемых свойств неверен, и вы видите ошибку. Понятия вложенных вычисляемых свойств как такового не существует, но вы можете создать единый сложный объект, который является результатом нескольких вычислений и создания единого значения, содержащего все данные, которые тебе нужно:

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

Каждый раз, когда text и formerResults изменяется какой-либо частью кода, ваш queries объект будет пересчитываться. Никакого штрафа за производительность как такового не будет.

Действительно ли мне нужно использовать вычисляемое свойство в моем примере, чтобы formerResults не было неопределенным в следующем запросе? Вы можете посоветовать, как содержать код в чистоте?

Использование вычисляемого свойства - самый чистый способ добиться реактивности. На мой взгляд, любая другая альтернатива громоздка. Например, вы можете сделать то же самое с помощью наблюдателей, но это не чисто.

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, ...
    };
  }
}
person Harshal Patil    schedule 26.04.2021
comment
Большое спасибо, Харшал, за аккуратный ответ и демонстрацию того, как вложить вычисленное свойство. Только одно пока не ясно: почему formerResults не реагирует? Параметры text и formerResults, которые я передал в time_1, являются соответственно строкой (переданной как опора) и пустой строкой ''. Результат запроса сохраняется в previousResults (vm.formerResults += /* add the results */), который я хочу передать в time_2 вместе с text. Так почему же в time_2 formerResults передается как undefined? Не могли бы вы это пояснить? - person user305883; 28.04.2021
comment
@ user305883 Сам formerResults не определен во время оценки q1, и этот undefined получает перенос, когда вы начинаете накапливать результат. Кроме того, простое определение q1 в зависимости от formerResults в функции data не делает q1 реактивным. Вам все еще нужно установить наблюдателей. Когда Vue.js говорит, что он является реактивным, это означает, что при изменении q1 или formerResults шаблоны будут отображаться снова. Это не означает, что когда formerResults изменяется, обновлять q1 автоматически. Для этого используются вычисляемые свойства. - person Harshal Patil; 28.04.2021