我正在根据组件页面顶部的标签列表中单击的内容来切换出组件中的数据。数据来自Vuex数据存储。通过测试Vuex数据存储,一切似乎都工作正常。我的Vue Chrome开发人员工具插件中的数据存储中有虚拟数据,似乎还可以。
当我在下面构造我的组件并尝试加载该页面时,控制台会抱怨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>
我建议您更改模板。尝试使用安全的导航:
<template>
<div>
...
<div>{{ currentObj && currentObj.amount }}</div>
</div>
<template>
或
<template>
<div>
...
<div v-if="currentObj">{{ currentObj.amount }}</div>
</div>
<template>
问题是currentObj
在某些时候未定义,这是不期望的。该症状可以像另一个答案所示一样对待,如果商店中可能缺少obj1
等,则很有用。仅当单击选项卡时obj1
等未定义时,才会发生这种情况:
试图用currentObj:{}替换数据的currentObj:this.obj1。同样的错误。
即使存储中有obj1
等,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
},
...