Отключение объекта на основе изменения данных в Vue (с Vuex) - PullRequest
0 голосов
/ 10 марта 2020

Я пытаюсь отключить данные, которые есть у меня в компоненте, на основе того, на что нажимали в списке вкладок в верхней части страницы моего компонента. Данные поступают из хранилища данных Vuex. После тестирования хранилища данных Vuex все работает нормально. В моем плагине Vue Chrome dev tools есть пустые данные в хранилище данных.

Когда я структурирую свой компонент, как показано ниже, и пытаюсь загрузить страницу, консоль жалуется Cannot read property 'amount' of undefined. Я предполагаю, что это потому, что данные загружаются до того, как вычисленные свойства находятся в Vue.

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


То, что я попробовал

-Попробовал заменить данные currentObj: this.obj1 на currentObj: {}. Та же ошибка.

- Попытка переместить свойство данных currentObj в вычисляемое свойство. Когда я делаю это, страница загружается, но я все равно получаю ту же ошибку, и когда я нажимаю на вкладки, мои данные не обновляются.


Любая идея, как я могу переключить данные в currentObj в моем компоненте?

<template>
  <div>
    <ul class="tabs">
      <li class="tab-title" v-on:click="tabSelection = 'tab1'">Tab 1</li>
      <li class="tab-title" v-on:click="tabSelection = 'tab2'">Tab 2</li>
      <li class="tab-title" v-on:click="tabSelection = 'tab3'">Tab 3</li>
    </ul>
    <div>{{ currentObj.amount }}</div>
  </div>
<template>

<script>
export default {
  data: function() {
    return {
      tabSelection: 'tab1',
      currentObj: this.obj1
    }
  },
  watch: {
    tabSelection: function(oldTabSelection, newTabSelection) {
      switch (newTabSelection) {
        case 'tab1':
          this.currentObj = this.obj1;
          break;
        case 'tab2':
          this.currentObj = this.obj2;
          break;
        case 'tab3':
          this.currentObj = this.obj3;
          break;
      }
    }
  },
  computed: {
    obj1: function() {
      return this.$store.getters.obj1;
    },
    obj2: function() {
      return this.$store.getters.obj2;
    },
    obj3: function() {
      return this.$store.getters.obj3;
    }
  }
}
</script>

Ответы [ 2 ]

1 голос
/ 10 марта 2020

Я рекомендую вам изменить свой шаблон. Попробуйте использовать безопасную навигацию:

<template>
  <div>
    ...
    <div>{{ currentObj && currentObj.amount }}</div>
  </div>
<template>

или

<template>
  <div>
    ...
    <div v-if="currentObj">{{ currentObj.amount }}</div>
  </div>
<template>
0 голосов
/ 11 марта 2020

Проблема в том, что currentObj не определен в какой-то момент, и это не ожидается. Симптом можно лечить, как показывает другой ответ, он может быть полезен, если obj1, et c. может отсутствовать в магазине. Это может произойти, только если obj1, et c. не определены в момент нажатия на вкладку:

Попытка заменить данные currentObj: this.obj1 на currentObj: {}. Та же ошибка.

Даже если obj1, et c. доступны в хранилище, вычисленное свойство obj1 недоступно в data, поскольку в данный момент экземпляр компонента еще не создан, так как для него требуются данные. data работает между beforeCreate и created перехватчиками.

Обходным решением будет вызвать геттер:

currentObj: this.$options.computed.getNumbers.call(this)

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

currentObj: this.$store.getters.obj1

И правильное решение - спроектировать компонент так, чтобы он не был проблемой. tabSelection наблюдатель не требуется, currentObj должно быть вычисляемым свойством, а не данными, поскольку оно вычисляется из tabSelection:

  computed: {
    currentObj() {
      let obj;
      switch (this.tabSelection) {
        case 'tab1':
          obj = this.obj1;
          break;
        case 'tab2':
          obj = this.obj2;
          break;
        case 'tab3':
          obj = this.obj3;
          break;
      }
      return obj || { amount: 'No amount' } // in case missing objs are expected
    },
    ...
...