2017-02-22 17 views
1

私はvotequestionまたはanswerのように、stackoverflowとよく似たWebサイトを作成しています。&簡単にするために、私は投票のためのコードを保持した。Vue.js 2.0同じコンポーネントが1つのアイテムにレンダリングされますが、他のアイテムは表示されません

これはquestionanswerの両方のコンポーネントで使用されているコンポーネントで、voteです。

<template> 
    <div class="vote"> 
    <h4 @click="voteUp"> 
     <i :class="{'fa fa-chevron-circle-up' : votedUp>-1, 'fa fa-chevron-up': votedUp==-1 }"></i> 
    </h4> 
    </div> 
</template> 

<script> 
    export default { 
    props: ['votes','item'], 
    computed:{ 
     votedUp() { 
     return _.findIndex(this.votes, {user_id: this.$root.authuser.id}); 
     } 
    }, 
    methods:{ 
     voteUp() { 
     axios.post(this.$root.baseUrl+'/vote_item', {item_id:this.item.id,item_model:this.item.model,vote:'up'}) 
      .then(response => { 
       _.isEmpty(response.data) ? this.votes.splice(this.votedUp,1) : this.votes.push(response.data); 
       }) 
     } 
    } 
    } 
</script> 

これはvoteコンポーネントを使用question成分である:

<template> 
    <div class="question"> 
    <h1>{{ question.title }}</h1> 
    <div class="row"> 
     <div class="col-xs-1"> 
     <vote :votes="question.votes" :item="item"></vote> 
     </div> 
     <div class="col-xs-11 pb-15"> 
     <p>{{ question.body }}</p> 
     <comment-list :comments="question.comments" :item="item" ></comment-list> 
     </div> 
    </div> 
    <answer v-for="answer in question.answers" :answer="answer"></answer> 
    </div> 
</template> 

<script> 
    export default { 
    props: ['question'], 
    data(){ 
     return { 
     item:{ id:this.question.id, model:'Question' } 
     }; 
    } 
    } 
</script> 

これはvoteコンポーネントを使用answer成分である:

<template> 
    <div class="answer row"> 
    <div class="col-xs-1 mt-20"> 
     <vote :votes="answer.votes" :item="item"></vote> 
    </div> 
    <div class="col-xs-11"> 
     <h3>{{ answer.title }}</h3> 
     <p>{{ answer.body }}</p> 
     <comment-list :comments="answer.comments" :item="item" ></comment-list> 
    </div> 
    </div> 
</template> 

<script> 
    export default { 
    props: ['answer'], 
    data(){ 
     return { 
     item:{ id:this.answer.id, model:'Answer' } 
     }; 
    } 
    } 
</script> 

問題

投票が正常に機能し、question.votesanswer.votesの両方の状態が変更されますが、HTMLのレンダリングはanswersのみです。私はquestionのupvoteを見るためにリフレッシュする必要があります。また、Vue developperツールコンソールでは、が自動的に更新され、vueの最新表示ボタンを押して、新しい投票を考慮してquestion.votesを表示する必要があります(ただし、HTMLは表示されません)。

あなたが見ることができるように

重要な注意、あなたもquestionanswercomment、これは私が$emitイベントに異なるアプローチを使用し、両方のために正常に動作していることができます。たぶんこれは私の答えの解決策ですが、実際に知りたいのはです。voteの機能はanswerで、questionでは機能していません。 ありがとう!

+0

開発モードでVueを使用していませんか?あなたは 'props'を変更/変更するべきではありません。 'vote'コンポーネントのように' this.votes.push'です。 –

+0

はいdevモードでVueを使用しています。私は代わりにそれをどうお勧めしますか? –

+0

その後、コンソールのVueから 'warn'を取得する必要があります。 –

答えて

1

voteのコンポーネントは、propsに変更しないでください。ローカルコピーを変更してください:

export default { 
    props: ['votes','item'], 
    data() { 
    return { votesCopy: [] }; 
    }, 
    mounted() { 
    this.votesCopy = this.votes.slice(); 
    }, 
    computed:{ 
    votedUp() { 
     return _.findIndex(this.votesCopy, {user_id: this.$root.authuser.id}); 
    } 
    }, 
    methods:{ 
    voteUp() { 
     axios.post(this.$root.baseUrl+'/vote_item', {item_id:this.item.id,item_model:this.item.model,vote:'up'}) 
      .then(response => { 
       _.isEmpty(response.data) 
       ? this.votesCopy.splice(this.votedUp,1) 
       : this.votesCopy.push(response.data); 
      }) 
    } 
    } 
} 
+0

ありがとう、ありがとう。しかし、私はまだコンポーネントが小道具を変異させてはならない理由を理解していません。説明していただけますか?なぜ私は小道具を交換する方が効率的なときに、私はメモリをコピーして負担しますか? –

+0

私は[この話題](https://forum-archive.vuejs.org/topic/4669/dealing-with-the-mutating-props-anti-pattern)が私よりも優れていると思います。 –

+0

すべてを同期させる正しい方法は、親の状態を変更するイベントを発行することです。あなたのソリューションは機能し、よりコードにやさしく(すべての投票ロジックは投票コンポーネントにとどまりますが)、親と子の状態の間で同期していない状態が作成されます。共有してくれてありがとう。 –

関連する問題