Vue.JS for 循环产生令人困惑的结果

Vue.JS for loop producing confusing results

第一次尝试 vue.js,我 运行 遇到了一个奇怪的问题。现在我的目标是在不同角色的戏剧中使用独特的线条颜色设置文本样式,这是我的代码:

<div id="app">
    <ul>
        <li v-for="part in scene">
            <span v-if="part.character = 'MACBETH'">
                <p>{{part.character}}</p>
                <p  v-bind:style="'color:red;'" >{{part.dialogue}}</p>
            </span>
            <span v-else-if="part.character = 'LADY MACBETH'">
                <p>{{part.character}}</p>
                <p v-bind:style="'color:blue;'" >{{part.dialogue}}</p>
            </span>
        </li>
    </ul>
</div>

<script>
var app = new Vue({
    el: '#app',
    
    data:{
        //Scene from http://shakespeare.mit.edu/macbeth/macbeth.1.7.html
        scene:[
            {character:'MACBETH', dialogue:"Hath he ask'd for me?"},
            {character:'LADY MACBETH', dialogue:"Know you not he has?"},
            {character:'MACBETH', dialogue:"We will proceed no further in this business:\nHe hath honour'd me of late; and I have bought\nGolden opinions from all sorts of people,\nWhich would be worn now in their newest gloss,\nNot cast aside so soon."},
            {character:'LADY MACBETH', dialogue:"Was the hope drunk\nWherein you dress'd yourself? hath it slept since?\nAnd wakes it now, to look so green and pale\nAt what it did so freely? From this time\nSuch I account thy love. Art thou afeard\nTo be the same in thine own act and valour\nAs thou art in desire? Wouldst thou have that\nWhich thou esteem'st the ornament of life,\nAnd live a coward in thine own esteem,\nLetting 'I dare not' wait upon 'I would,'\nLike the poor cat i' the adage?"}   
        ]
        //Next line
        //MACBETH

        //Prithee, peace:
        //I dare do all that may become a man;
        //Who dares do more is none.
    }
    
});
</script>

预期的结果是麦克白的台词显示为红色,麦克白夫人的台词显示为蓝色,但是由于它目前的功能,我的输出如下所示:

正在更改角色名称,麦克白夫人台词的所有文字都是红色而不是蓝色。

有什么指点吗?我对此很陌生,所以仍在努力弄清楚基础知识。

比较 v-if/v-else-if 指令中的两个值时,您需要使用 == 而不是 =

<div id="app">
    <ul>
        <li v-for="part in scene">
            <span v-if="part.character == 'MACBETH'">
                <p>{{part.character}}</p>
                <p  v-bind:style="'color:red;'" >{{part.dialogue}}</p>
            </span>
            <span v-else-if="part.character == 'LADY MACBETH'">
                <p>{{part.character}}</p>
                <p v-bind:style="'color:blue;'" >{{part.dialogue}}</p>
            </span>
        </li>
    </ul>
</div>

<script>
var app = new Vue({
    el: '#app',
    
    data:{
        //Scene from http://shakespeare.mit.edu/macbeth/macbeth.1.7.html
        scene:[
            {character:'MACBETH', dialogue:"Hath he ask'd for me?"},
            {character:'LADY MACBETH', dialogue:"Know you not he has?"},
            {character:'MACBETH', dialogue:"We will proceed no further in this business:\nHe hath honour'd me of late; and I have bought\nGolden opinions from all sorts of people,\nWhich would be worn now in their newest gloss,\nNot cast aside so soon."},
            {character:'LADY MACBETH', dialogue:"Was the hope drunk\nWherein you dress'd yourself? hath it slept since?\nAnd wakes it now, to look so green and pale\nAt what it did so freely? From this time\nSuch I account thy love. Art thou afeard\nTo be the same in thine own act and valour\nAs thou art in desire? Wouldst thou have that\nWhich thou esteem'st the ornament of life,\nAnd live a coward in thine own esteem,\nLetting 'I dare not' wait upon 'I would,'\nLike the poor cat i' the adage?"}   
        ]
        //Next line
        //MACBETH

        //Prithee, peace:
        //I dare do all that may become a man;
        //Who dares do more is none.
    }
    
});
</script>

您应该查看 vue documentation - 如何根据条件设置元素样式。您可以像这样使用 :style binding:class binding

Vue.createApp({
  data() {
    return {
      scene:[
          {character:'MACBETH', dialogue:"Hath he ask'd for me?"},
          {character:'LADY MACBETH', dialogue:"Know you not he has?"},
          {character:'MACBETH', dialogue:"We will proceed no further in this business:\nHe hath honour'd me of late; and I have bought\nGolden opinions from all sorts of people,\nWhich would be worn now in their newest gloss,\nNot cast aside so soon."},
          {character:'LADY MACBETH', dialogue:"Was the hope drunk\nWherein you dress'd yourself? hath it slept since?\nAnd wakes it now, to look so green and pale\nAt what it did so freely? From this time\nSuch I account thy love. Art thou afeard\nTo be the same in thine own act and valour\nAs thou art in desire? Wouldst thou have that\nWhich thou esteem'st the ornament of life,\nAnd live a coward in thine own esteem,\nLetting 'I dare not' wait upon 'I would,'\nLike the poor cat i' the adage?"}   
      ]
    }
  },
  methods: {
  }
}).mount('#demo')
.red {
  color: red;
}
.blue {
  color: blue;
}
<script src="https://unpkg.com/vue@next"></script>

<div id="demo" class="demo">
  <ul>
    <li v-for="part in scene" :key="part.id">
          <p>{{ part.character }}</p>
          <p :class="[
            { 'red': part.character === 'MACBETH' },
            { 'blue': part.character === 'LADY MACBETH'  }
          ]" >{{part.dialogue}}</p>
    </li>
  </ul>
</div>

通过这种方法,您可以删除 if/else 条件以保持模板清洁。

答案令人惊讶的是 none 添加了非常重要的 v-for 属性 -> key.

即使这不是缺少此属性的问题,但建议始终添加 key 作为最佳实践。

如果每个迭代项都有一个 ID,您可以这样做:

v-for="part in scene" :key="part.id"

或者使用索引

v-for="(part,index) in scene" :key="part.index"

更多信息here