如何将 class 切换到 v-for 中的单个元素

how to toggle class to a single element inside a v-for

我是 vueJs 的新手,我正在尝试在您单击后将 class "active" 切换为单个元素。这是我的代码 使用 class material_icons 切换所有元素。如何做到只切换点击的元素? 谢谢。 我的 HTML:

 <div v-for="(listArtist, index) in listArtists" class="col s4 center" id="art">
<p> {{ listArtist.title_short }}</p>
<p>{{ listArtist.artist.name }} </p>
<p>{{ listArtist.album.title }}</p>
<div id="margin-test">   
    <i class="material-icons" @click="fav(listArtist.title,listArtist.album.title,listArtist.artist.name,listArtist.id)"  v-bind:class="{'active': color}">favorite_border</i>
</div>

我的 js :

data: {
listArtists:[],
color: false,
}

fav: function(titleTrack, album, artist, id ){
            this.color = !this.color
}

问题是你目前只有 一个 color 标志和多个艺术家元素。

要让它发挥作用,您必须找到一种方法来代替 多个 colors 标志,每个艺术家一个。

你基本上可以用两种形式来做:

  • 您可以将color声明为辅助对象并使用id作为键(下面的演示1)。
    • color 设为数组并使用 indexv-for 的)代替 id.
    • 也可以实现同样的效果
    • 这种方法的优点是不向您当前的艺术家元素添加任何属性。
  • 您还可以在每个艺术家中声明一个 color 属性 并改为使用它(下面的演示 2)。
    • 这有点干净,但确实需要添加 color 属性。

Demo 1(使用color作为分隔对象或数组)

new Vue({
  el: '#app',
  data: {
    message: 'Hello Vue.js!',
    listArtists: [
     {id: 1, title: 'title1', title_short: 'title_short1', artist: {name: 'artist.name1'}, album: {title: 'album.title1'}},
      {id: 2, title: 'title2', title_short: 'title_short2', artist: {name: 'artist.name2'}, album: {title: 'album.title2'}}
    ],
    color: {},
  },
  methods: {
    fav: function(titleTrack, album, artist, id) {
      this.$set(this.color, id, !this.color[id]);
    }
  }
})
.active {
  color: red;
}
<script src="https://unpkg.com/vue"></script>

<div id="app">
  <div v-for="(listArtist, index) in listArtists" class="col s4 center" id="art">
    <p> {{ listArtist.title_short }}</p>
    <p>{{ listArtist.artist.name }} </p>
    <p>{{ listArtist.album.title }}</p>
    <div id="margin-test">
      <i class="material-icons" @click="fav(listArtist.title,listArtist.album.title,listArtist.artist.name,listArtist.id)" v-bind:class="{'active': color[listArtist.id]}">favorite_border</i>
    </div>
  </div>
</div>

演示 2(在每个元素上使用 color 属性)

new Vue({
  el: '#app',
  data: {
    message: 'Hello Vue.js!',
    listArtists: [
     {id: 1, title: 'title1', title_short: 'title_short1', artist: {name: 'artist.name1'}, album: {title: 'album.title1'}},
      {id: 2, title: 'title2', title_short: 'title_short2', artist: {name: 'artist.name2'}, album: {title: 'album.title2'}}
    ],
    color: {},
  },
  methods: {
    fav: function(titleTrack, album, artist, id, listArtist) {
      this.$set(listArtist, 'color', !listArtist.color);
    }
  }
})
.active {
  color: red;
}
<script src="https://unpkg.com/vue"></script>

<div id="app">
  <div v-for="(listArtist, index) in listArtists" class="col s4 center" id="art">
    <p> {{ listArtist.title_short }}</p>
    <p>{{ listArtist.artist.name }} </p>
    <p>{{ listArtist.album.title }}</p>
    <div id="margin-test">
      <i class="material-icons" @click="fav(listArtist.title,listArtist.album.title,listArtist.artist.name,listArtist.id,listArtist)" v-bind:class="{'active': listArtist.color}">favorite_border</i>
    </div>
  </div>
</div>

一个简单的解决方案:

  1. @click="fav中,让selectedItem=当前选择(=listArtist)

  2. 然后使用v-bind:class="{'active': selectedItem == listArtist}"

而且你的代码有一个问题,你最好提供the unique key for each item

new Vue({
    el: "#app",
    data: {
        listArtists: 
        [
          {id:1,'title_short':'Test-A',artist:{name:'Name-A'}, album:{title:'Title-A'}},
          {id:2,'title_short':'Test-B',artist:{name:'Name-B'}, album:{title:'Title-B'}},
          {id:3,'title_short':'Test-C',artist:{name:'Name-C'}, album:{title:'Title-C'}}        
        ],
        selectedItem: null
    },
    methods: {
      fav: function(listArtist, titleTrack, album, artist, id ){
        this.selectedItem = listArtist
      }
    }
});
.active{
  background-color:red
}
<script src="https://unpkg.com/vue@2.0.1/dist/vue.js"></script>
<div id="app">
  <div v-for="(listArtist, index) in listArtists" class="col s4 center" :key="index">
  <p> {{ listArtist.title_short }}</p>
  <p>{{ listArtist.artist.name }} </p>
  <p>{{ listArtist.album.title }}</p>
  <div id="margin-test">   
      <i class="material-icons" @click="fav(listArtist, listArtist.title,listArtist.album.title,listArtist.artist.name,listArtist.id)"  v-bind:class="{'active': selectedItem == listArtist}">favorite_border</i>
  </div>
</div>