Vue.js 2.0 在一个项目上呈现相同的组件,但在另一个项目上不呈现

Posted

技术标签:

【中文标题】Vue.js 2.0 在一个项目上呈现相同的组件,但在另一个项目上不呈现【英文标题】:Vue.js 2.0 same component rendering on one item but not another 【发布时间】:2017-07-11 22:12:50 【问题描述】:

我正在建立一个类似于 *** 的问答网站,您可以在其中 vote questionanswer。为简化起见,我保留了用于投票的代码。

这是vote 组件,用于questionanswer 组件。

<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 的状态,但它只呈现answershtml。我必须刷新才能看到对question 的支持。同样在 Vue 开发者工具控制台中,answer.votes 会自动刷新,而我需要点击 vue 刷新按钮才能看到 question.votes 考虑到新投票(但仍然没有 HTML 呈现)。

重要提示

如您所见,您还可以在questionanswer 上使用comment,这对两者都有效,因为我对$emit 事件使用了不同的方法。也许这是我回答的一个解决方案,但我真正想知道的是为什么vote 中的功能在answer 上工作而不是question。 谢谢!

【问题讨论】:

没有在开发模式下使用 Vue?你不应该改变/改变props。就像在 vote 组件中一样 - this.votes.push 是的,我在开发模式下使用 Vue。你建议我怎么做? 那么你应该在控制台中有一个来自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);
            )
    
  

【讨论】:

它有效,谢谢。但我仍然不明白为什么组件不应该改变道具。你能解释一下吗?当更改道具更有效时,我为什么要复制和负担内存? 我猜this discussion 解释得比我还好。 似乎保持一切同步的正确方法是发出事件来改变父级的状态。您的解决方案有效并且对代码更友好(所有投票逻辑都保留在投票组件中),但会在父状态和子状态之间创建不同步的状态。感谢分享。 最后一个问题:你为什么要在 mount() 中分割选票?我用 data() return votesCopy: this.votes; 和它的工作原理 好吧,那好吧。这是我创建数组副本的方式。

以上是关于Vue.js 2.0 在一个项目上呈现相同的组件,但在另一个项目上不呈现的主要内容,如果未能解决你的问题,请参考以下文章

vue.js 2.0 通信最佳实践

一个为 Vue JS 2.0 打造的 Material 风格的组件库

无法从嵌套组件中的资产文件夹加载图像(Vue.js 2.0 / Webpack)

Vue.js 2.0 | P2 双向绑定和vue-devtools

如何使用Vue.js获取呈现dom元素的组件

Vue.js高仿饿了么外卖App 前端框架Vue.js 1.0升级2.0