2017-07-08 113 views
0

我一直在处理使用Vue,Vuex和Vue-Router的问题。我正在构建一个闪存卡应用程序,在创建主应用程序时获取所有卡,然后使用Vuex getter通过其作为路由参数传递的id获取每张卡。渲染函数错误:“TypeError:无法读取未定义的属性”,使用Vuex和Vue路由器

相关位:

App.vue

export default { 
    components: { 
    'app-header': header, 
    }, 
    data() { 
    return { 
    } 
    }, 
    created() { 
    this.$store.dispatch('getAllCards'); 
    } 
} 

dispatch('getAllCards')只是拉从数据库中所有的牌,并承诺Vuex store.js

现在我成立了一个getter

getters: { 
    cardById: (state) => (id) => { 
    return state.allCards.find((card) => card._id === id); 
    } 
} 

这里是Card.vue

<template> 
    <div> 
    <br> 
    <div v-if="flipped" class="container"> 
     <div class="box"> 
     <pre v-if="card.code"><code class="preserve-ws">{{card.back}}</code></pre> 
     <p class="preserve-ws center-vertical" v-else>{{card.back}}</p> 
     </div> 
    </div> 
    <div v-else class="container"> 
     <div class="box"> 
     <h1 class="title has-text-centered center-vertical is-2">{{card.front}}</h1> 
     </div> 
    </div> 
</template> 

<script> 

export default { 
    data() { 
    return { 
     card: {}, 
     flipped: false, 
     general_card: false, 
     code_card: true, 
     random_card: false 
    } 
    }, 
    computed: { 
    }, 
    methods: { 
    }, 
    created() { 
    this.card = this.$store.getters.cardById(this.$route.params.id); 
    } 
} 
</script> 

我得到的标题中引用的类型错误。我的理解是created()挂钩发生在data()设置完成后,所以我可以使用getter分配{card}。很不幸,这显示什么...

如果我给你card()作为计算性能:

computed: { 
    card() { 
    return this.$store.getters.cardById(this.$route.params.id); 
    } 
} 

卡显示,但我仍然得到这个错误控制台。任何想法为什么?我看着this并试图解决,但无济于事。

回答

0

我认为这是错误扔在这一步

getters: { 
    cardById: (state) => (id) => { 
    return state.allCards.find((card) => card._id === id); 
    } 
} 

在这一步,实在找不到车_id,因为allcards是null;

然后你用计算器代替,当所有卡都改变时,它会重新得到; 你可以改变这样的

getters: { 
    cardById: (state) => (id) => { 
    return state.allCards.find((card) => card && card._id === id); 
    } 
} 
+0

对不起,我本来应该更具体的...我得到确切的错误是: '[Vue公司提醒]:错误的渲染功能:“类型错误:无法读取属性‘前’的未定义”' 您的解决方案并没有真正做任何事情。 – Aos

+0

在我最近的评论中不意味着粗鲁。无论如何,错误追溯显示它出现在'Card.vue'组件中。 – Aos

+0

它有一个简单的解决方案,你可以使用'card && card.front'来代替,然后不会抛出错误,但是我不能发现的真正原因 – masongzhi

0

$route.params.id代码必须string,那么什么是card._id类型?看来每个card._idnumber,我想。

+0

当做'typeof card._id'时,我返回一个字符串。 – Aos

1

您需要的是基于商店状态的派生状态,该状态是基于卡片ID返回已过滤的卡片。这个ID通过路由参数被接收到你的组件。因此,它更好地使用一个计算的属性,而不是传递参数到店干将

而是在数据属性初始化card的使card一个计算的属性是这样的:

computed:{ 
    card(){ 
     return this.$store.state.allCards.find((card) => card._id === this.$route.params.id); 
    } 
} 

注意这个

如果一个组件需要基于它自己的状态派生的存储状态(在你的情况下是rourte params),它应该定义一个本地计算的属性

1

我试过别人的解决方案,他们没有工作。但我最终得到了它的工作。这里是我工作:

我结束了包括顶级:

<div v-if="!card"> Loading card... </div> 
<div v-else> Rest of card template </div> 

这似乎已经关闭了错误。此外,该卡的生命作为计算性能:

card() { 
    return this.$store.getters.cardById(this.$route.params.id); 
} 
0

问题没有所有的前提下,得到一个正确的答案。 (我们不知道的突变,状态,既没有行动,我们也没有关于应用头组件线索) 因此,我们不得不承认一些假设:

  1. state.allCards是一个空Array当你安装该组件
  2. 行动getAllCards是一个异步函数与突变检索或设置state.allCards

cardById的干将,返回的函数,所以vuex不能在功能应用反应。所以如果状态改变,吸气剂将不会被正确触发。 要解决此问题,请使用computed,正如您提到的here

但是它并没有修复undefined error,从我的角度来看,是因为getter在mount上返回undefined

getters: { 
    cardById: (state) => (id) => { 
    var card = state.allCards.find((card) => card._id === id); 
    if(card) { 
     return card; 
    } 
    // on undefined return a default value 
    return { 
     front:'default value' 
    }; 
    } 
} 

你可以看到这个jsfiddle上的实现,在控制台上没有错误。

或者您的卡组件的未定义值可以有加载状态。

如果我的假设错了,请提供一个jsfiddle来帮助你。

相关问题