我正在尝试使用通过Vuex中的mapGetters函数提取的数据来创建计算属性,但是在页面/dom完全加载之前,我总是变得不确定。

这是一个isRegistered计算属性的示例,我用它来隐藏/显示某些按钮。

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

这是使用isRegistered计算属性的按钮的HTML。
<a href="#" class="register-button" v-if="!isRegistered">REGISTER NOW</a>
<a href="#" class="registered-button" v-if="isRegistered">REGISTERED</a>

我通过在创建的函数中调用的操作来设置 setter/getter
created () {
      this.getTournament('solos').catch(err => {})
}

这是我设置相应 setter/getter 的 Action
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;
  }
};

这是对应的 setter/getter
const getters = {
   solos (state) {
     return state.solos
   }
}

我遇到的问题是,在PAGE/DOM完全加载之前,该值最初显示为未定义,从而导致.indexOf引发以下错误:
TypeError: Cannot read property 'indexOf' of undefined

我能够使它起作用的唯一方法是在计算属性上使用if语句,该语句检查状态数据是否已加载。
isRegistered () {
  if (this.solos._id) return this.solos.registered.indexOf(this.user._id) !== -1
}

这似乎不是正确的处事方式。我究竟做错了什么?

最佳答案

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

created钩子(Hook)上,将初始化组件的计算属性,观察者和数据(同步运行 ),但是solos getter在promise中运行(异步运行 ),因此生命周期将继续进行,而无需完成 promise 。

创建的 Hook 完成后,将创建观察者,这意味着如果数据发生更改,它们将反射(reflect)在DOM上,但是只有在Promise返回结果之后,才会填充独奏。因此,在应用程序初始化时, promise 不会结束,但是一旦结束,数据就会更新并显示。

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

09-17 07:44