首页 > 解决方案 > 如何在 VueJS 中的按钮上切换背景颜色

问题描述

我正在使用 VueJS,并且我有一个动态创建的流派按钮列表。这些按钮可以打开和关闭,当它们打开时,我想应用 CSS 样式(如蓝色背景)来显示它们被选中。当它们未被选中时,我希望它恢复原状(带有灰色边框的白色背景)。

我的问题是我无法实现切换背景颜色功能。我曾尝试使用variant="primary"以及其他变体选项,但它不起作用。我也尝试过style="border: 2px solid darkgrey; margin:2px;"在应用时擦除variant,但这也不起作用。

我已经尝试使用StackOverflow post直接更改按钮的 CSS ,但它不起作用。

这是我的 index.html 中的按钮标记:

<ul style="list-style: none;">
    <button v-if="ShowALLButton" v-on:click="getAllGenres" class = "btn btn-success" style="left: 0px; margin:2px;">ALL</button>
        <li style="display: inline;">
          <button v-for="buttons in buttonsList" v-if="ShowALLButton" v-on:click="getGenre(buttons)" :pressed.sync="buttons.state" id="buttonID" class = "btn" style="border: 2px solid darkgrey; margin:2px;">
            {{ buttons.genre }}. 
          </button>
        </li>
</ul>

本质上,上面是一个遍历我的buttonsList的for循环,它是一个看起来像这样的结构,包含要在按钮上显示的流派,以及它是否已打开或关闭(由状态指示,即最初关闭,如false) 所示。实际的切换功能有效,因为它显示了正确的流派结果。但是对于那些好奇的人来说,这就是 buttonList 的样子(对象列表):

[
{ genre: "Folk", state: false },
{ genre: "Rap", state: false },
{ genre: "Pop", state: false },
...
]

index.html 中的相关样式:

<style>
 .am-active {
    background-color: rgb(21, 79, 202);
    color: white;
 }
 .am-not-active {
    background-color: white;
 }
</style>

处理按钮切换和流派选择的函数在我的 script.js 中。我todo!需要应用正确的 CSS 样式来更改按钮,但我做不到。

// Get Selected Genres
getGenre(button) {
  console.log("ENTERED GET GENRE!!!!!!");
  var selectedGenresItems = []

  // keep track of selected genres
  if (!this.selectedGenres.includes(button)) {
    this.selectedGenres.push(button);
    // todo!
    console.log("inside if");
    button.className += 'am-active';
    console.log(button);
    // ^ the above does not work, it just adds a key with "className" = "undefinedam-active" :(
  }
  else {
    this.selectedGenres.pop(button);
    // todo! must use .am-not-active
  }

  // you can stop reading here if you want
  // print out the list 
  console.log("selectedGenres here:");
  console.log(this.selectedGenres);

  // get only items that have the desired genre
  var num_matches= 0;
  console.log("items length:" + this.items.length);
  console.log("selectedGenres length:" + this.selectedGenres.length);
  for (var start = 0; start < this.items.length; start++) {
    for (var g = 0; g < this.selectedGenres.length; g++) {
      if (this.items[start].primaryGenreName === this.selectedGenres[g].genre) {
        console.log("we found a match!!!");
        num_matches++;
        selectedGenresItems.push(this.items[start]);
      }
    }
  }

  console.log("num_matches: " + num_matches);
  console.log("this is my final list of selectedGenreItems:")
  console.log("object: %O", selectedGenresItems);

  // assign this list to filteredItems (which renders on index.html)
  this.filteredItems = [];
  this.filteredItems = selectedGenresItems;

  // print out the items in this list
  console.log("items in filteredItems:");
  console.log(this.filteredItems);
}

标签: javascripthtmlcssvue.js

解决方案


您可以根据状态键绑定class属性并启用/禁用类。statebuttonsList

new Vue({
  el: '#app',
  
  data: {
    buttonsList: [
      { genre: "Folk", state: false },
      { genre: "Rap", state: false },
      { genre: "Pop", state: false },
    ]
  },
  
  methods: {
    getGenre (buttons, i) {
      this.buttonsList[i].state = !this.buttonsList[i].state
    }
  }
})
.am-active {
    background-color: rgb(21, 79, 202);
    color: white;
 }
 .am-not-active {
    background-color: white;
 }
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>

<div id="app">

  <ul>
    <li>
      <button 
        v-for="(buttons, i) in buttonsList" v-on:click="getGenre(buttons, i)"
        :class="{
          'am-active': buttons.state,
          'am-not-active': !buttons.state
        }"
        :key="i"
      >
        {{ buttons.genre }}. 
      </button>
    </li>
  </ul>

</div>


推荐阅读