我正在尝试使用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
}
这似乎不是一种正确的做事方式。我做错了什么?
答案 0 :(得分:10)
问题可能与vue生命周期有关。
在created挂钩处,计算出的属性,观察者和组件数据被初始化(运行同步),但 solos getter在promise中运行(运行异步),因此生命周期会在没有承诺完成的情况下继续。
当创建挂钩完成后,观察者就会被创建,这意味着如果数据发生了变化,它们将反映在DOM上,但是在承诺返回后,仅结果,独奏将被填补。因此,在应用程序初始化时,承诺未结束,但一旦结束,数据就会更新并显示。
避免此错误的一种方法是使用v-if="solos.registered"
,但我仍在寻找更好的解决方法。