Vue.js — Добавить класс к нажатой кнопке

#vue.js #vuejs2 #click #vue-class-components

Вопрос:

Следующий код предназначен для отображения нескольких продуктов, отображаемых брендом. когда вы нажмете кнопку бренда, на ней отобразится его продукция. это работает нормально, однако я добавил фильтр к логотипу бренда, чтобы он выглядел серым, пока вы не наведете на него курсор. теперь я хочу, чтобы этот фильтр не менялся на «нет», как только вы нажмете кнопку.

До сих пор я только удалил фильтр со всех брендов, что противоречит цели выделения нажатой кнопки. Как я могу применить класс active только к одной кнопке, той, которую нажимает пользователь?

HTML:

 <template>
  <div>
    <div class="buttonBrand">
      <button v-for="(element, index) in brand"   :key="index" :class='{buttonActive : isActive  }' @click="changeBrand(index)">
        <img v-bind:src="element.imageBrand" alt />
      </button>
    </div>
    <div class="product-wrapper">
      <single-product-new v-for="(element,index) in object" :key="index" :element="element" />
    </div>
  </div>
</template>
 

scss:

 .buttonBrand {
    display: flex;

    button {
        margin: 25px auto;
        justify-content: space-between;
        img {
           filter: grayscale(100%) contrast(30%);
        }
        img:hover {
            filter: none;

        }

        .is-active {
            img {
                filter: none;

            }
          }
    }
    .buttonActive {
        img {
            filter: none;
        }
    }

}
 

JS:

 
const singleProductNew = () => import("../singleProductNew/singleProductNew.vue");

export default {
    // COMPONENTS
    components: {
        singleProductNew
    },

    props: {

    },



    // DATA
    data() {
        return {
            isActive: false,
            object: null,
            brand: [{
                title: 'lg',
                imageBrand: "/img/lg.png",
                products: [{
                    volume: "123",
                    energyseal: "A  ",
                    dimensions: "123",
                    wattage: "123",
                    color: [{
                        price: "123",
                        fee: "111",
                        reference: "asdasdasda",
                        colorName: "white",
                        availability: "yes",
                        image: '/img/hot_1.png'

                    },
                    {
                        price: "321",
                        fee: "222",
                        reference: "23123",
                        colorName: "gray",
                        availability: "no",
                        image: '/img/hot_1_b.png'
                    }
                    ]
                },
                {
                    volume: "123",
                    energyseal: "A  ",
                    dimensions: "123",
                    wattage: "123",
                    color: [{
                        price: "123",
                        fee: "333",
                        reference: "123",
                        colorName: "gray",
                        availability: "yes",
                        price: "123",
                        image: '/img/hot_2.png'

                    },]
                }

                ],


            },
            {
                title: 'samsung',
                imageBrand: "/img/samsung.png",
                products: [{
                    volume: "333",
                    energyseal: "A  ",
                    dimensions: "123",
                    wattage: "123",
                    color: [{
                        price: "888",
                        fee: "77",
                        reference: "123",
                        colorName: "white",
                        availability: "yes",
                        image: '/img/sam_1.png'

                    },
                    {
                        price: "321",
                        fee: "123",
                        reference: "23123",
                        colorName: "gray",
                        availability: "no",
                        image: '/img/sam_1_b.png'
                    }
                    ]
                },
                {
                    volume: "1123",
                    energyseal: "A  ",
                    dimensions: "123",
                    wattage: "123",
                    color: [{
                        price: "123",
                        fee: "123",
                        reference: "123",
                        colorName: "gray",
                        availability: "yes",
                        price: "123",
                        image: '/img/sam_2.png'
                    },]
                }
                ],
            },
            ]
        }
    },

    mounted() {
        this.object = this.brand[0].products;

    },
    // METHODS
    methods: {
        changeBrand(index) {
            this.object = this.brand[index].products;
            if(this.isActive){
                this.isActive = false;
              }else{
                this.isActive = true;
              }


        }

    }
}

 

как упоминалось выше buttonActive , класс применяется ко всем кнопкам, и я просто хочу, чтобы он был применен к нажатой кнопке.

Ответ №1:

Попробуйте добавить другое вызываемое свойство объекта данных currentIndex и обновить его до индекса нажатой кнопки :

 // DATA
data() {
    return {
         currentIndex:-1,
        isActive: false,
           ...
 

внутри шаблона свяжите класс следующим образом :class='{buttonActive : (index==currentIndex) }' :

 <div class="buttonBrand">
  <button v-for="(element, index) in brand"   :key="index" :class='{buttonActive : (index==currentIndex)  }' @click="changeBrand(index)">
    <img v-bind:src="element.imageBrand" alt />
  </button>
</div
 

методы :

     changeBrand(index) {
        this.object = this.brand[index].products;
        this.currentIndex=index;


    }