Как я могу покрасить фон нескольких выбранных элементов в Vue?

У меня есть код ниже для выбора категории. Когда категория выбрана, ее фон становится зеленым, в противном случае фон становится серым; это работает нормально.

Чего я хочу добиться, так это того, что когда я выбираю несколько элементов, я хочу, чтобы фон оставался зеленым для всех выбранных категорий. Есть ли способ сделать это?

<div class = "categories" v-for = "(category, index) in categories" :key = "index" @click = "Add( category._id, index)" :class = "[isediting && selectedIndex == index ? 'green' : 'gray']">
  {{ category.category_name }}
</div>

<script>
  methods: {
      Add(AddCategory, index) {
        this.AddCategory.push(AddCategory);
        this.selectedIndex = index;
        this.isediting = true;
      },
</script>

<style>
  .green {
    background-color: #41B883;
  }
  
  .gray {
    background-color: #e5e0ed;
  }
</style>

🤔 А знаете ли вы, что...
JavaScript является одним из трех основных языков веб-разработки, вместе с HTML и CSS.


1
676
2

Ответы:

Решено

Единственное серьезное изменение, которое необходимо внести, чтобы приспособиться к этому, — сделать selectedIndex массив, а не одно значение, чтобы мы могли удерживать более одного выбора.

Например.:

  1. Установите selectedIndex в массив [] в data()
  2. При нажатии мы должны поместить значение в массив вместо того, чтобы устанавливать его равным
  3. Чтобы проверить, выбран ли данный индекс, мы используем selectedIndex.includes(index) вместо selectedIndex == index

Однако есть еще один побочный эффект множественного выбора, который заключается в добавлении поддержки отмены выбора по щелчку. Но это также довольно просто, нам просто нужно проверить, содержит ли уже selectedIndex значение в Add(), и если да, то удалить его. Для этого мы можем использовать Array.prototype.splice().

Вот интерактивная версия:

new Vue({
  el: '#app',
  data() {
    return {
      selectedIndex: [],
      categories: [{ _id: 0, category_name: 'noodles' }, { _id: 1, category_name: 'pizza' }, { _id: 2, category_name: 'hamburgers' } ],
    }
  },
  methods: {
    Add(AddCategory, index) {
      //Check if item is selected...
      if (this.selectedIndex.includes(index)) 
        this.Remove(index); //If so, remove from selectedIndex
      else
        this.selectedIndex.push(index); //If not, add to selectedIndex
    },
    Remove(index) { //Find index in selectedIndex, and splice out
      this.selectedIndex.splice(this.selectedIndex.indexOf(index),1);
    },
    RemoveAll() { //To deselect all, we empty the selectedIndex array
      this.selectedIndex = [];
    },
  }
});
.green {
  background-color: #41B883;
}

.gray {
  background-color: #e5e0ed;
}
<script src = "https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.min.js"></script>

<div id = "app">
  <div v-for = "(category, index) in categories" 
    @click = "Add( category._id, index)" 
    :class = "[selectedIndex.includes(index) ? 'green' : 'gray']"
  >
    {{ category.category_name }}
  </div>
  <br>
  <button @click = "RemoveAll">Unselect All</button>
</div>

Это потому, что вы делаете это на основе index, поэтому index уникален и также меняется при каждом нажатии. Попробуйте свойство для каждой категории, например selected, и сделайте его ложным по умолчанию. Затем в вашей функции щелчка просто выполните this.categories[index].selected = !this.categories[index].selected. После этого привяжите класс к значению category.selected.