计算属性中的Vuex getter在整页加载前显示未定义

时间:2017-05-25 17:31:57

标签: javascript vue.js vuex

我正在尝试使用vuex中使用mapGetters函数提取的数据创建计算属性,但我总是未定义,直到页面/ dom完全加载。

这是一个用于隐藏/显示某些按钮的isRegistered computed属性的示例。

computed: {
      ...mapGetters(['solos', 'user']),
      isRegistered () {
        return this.solos.registered.indexOf(this.user._id) !== -1
      }
}

以下是使用isRegistered computed属性的按钮的HTML。

<a href="#" class="register-button" v-if="!isRegistered">REGISTER NOW</a>
<a href="#" class="registered-button" v-if="isRegistered">REGISTERED</a>

我通过我在创建的函数中调用的动作设置getter

created () {
      this.getTournament('solos').catch(err => {})
}

这是我设置相应getter的操作

getTournament: ({commit}, type) => {
    return feathers.service('tournaments').find({
      query: {
        type: type,
        status: 'registering'
      }
    }).then(tourney => {
      commit(type.toUpperCase(), tourney.data[0])
    })
}

这是相应的突变

const mutations = {
  SOLOS (state, result) {
    state.solos = result;
  }
};

这是相应的getter

const getters = {
   solos (state) {
     return state.solos
   }
}

我遇到的问题是,在PAGE / DOM完全加载之前,该值最初显示为undefined,导致.indexOf抛出以下错误:

TypeError: Cannot read property 'indexOf' of undefined

我能够让它工作的唯一方法是在计算属性上使用if语句来检查状态数据是否已经加载。

isRegistered () {
  if (this.solos._id) return this.solos.registered.indexOf(this.user._id) !== -1
}

这似乎不是一种正确的做事方式。我做错了什么?

1 个答案:

答案 0 :(得分:10)

问题可能与vue生命周期有关。

created挂钩处,计算出的属性,观察者和组件数据被初始化(运行同步),但 solos getter在promise中运行(运行异步),因此生命周期会在没有承诺完成的情况下继续。

创建挂钩完成后,观察者就会被创建,这意味着如果数据发生了变化,它们将反映在DOM上,但是在承诺返回后,结果,独奏将被填补。因此,在应用程序初始化时,承诺未结束,但一旦结束,数据就会更新并显示。

避免此错误的一种方法是使用v-if="solos.registered",但我仍在寻找更好的解决方法。