Как поменять фон блоков div по клику в VUE

Есть 5 блоков div: Нужно чтобы при нажатии на любой из них менялся цвет фона у этого блока, и пропадал у другого. По умолчанию цвет фона у всех одинаковый


Ответы (4 шт):

Автор решения: Антон Иванов

блок у которого будет пропадать цвет рандомный? И правильно ли понял задачу: 5 блоков одинакового цвета. Кликаем на любой у произвольного меняется цвет(на какой?) по итогу все блоки разноцветные или просто имеем постоянно 1 (нажатый последним) блок другого цвета? И в дополнение блоки имеют классы или id, одинаковые или разные, или это просто чистые div-ы?

    <div class="block">
        <div id="a1">
        one
        </div>
        <div id="a2">
        two
        </div>
          ...
        <div id="a5">
        five
        </div>
    </div>



  let i=0;
$('div').click(function() {
    i=Math.floor(Math.random() * 5);
    if ($(this).attr('id') === 'a1') {
    this.style.backgroundColor="white";
    $('#a'+i).css('background-color','gray');
    }else
    if ($(this).attr('id') === 'a2') {
        this.style.backgroundColor="white";
        $('#a'+i).css('background-color','gray')} else
        if ($(this).attr('id') === 'a3') {
            this.style.backgroundColor="white";
            $('#a'+i).css('background-color','gray')}else
            if ($(this).attr('id') === 'a4') {
                this.style.backgroundColor="white";
                $('#a'+i).css('background-color','gray')}else
                if ($(this).attr('id') === 'a5') {
                    this.style.backgroundColor="white";
                    $('#a'+i).css('background-color','gray')}

не знаю насколько это красиво, но должно работать. Только осваиваю js. Правда это через jquery, но можно легко исправить на чистый js

→ Ссылка
Автор решения: Александр Сычёв

Решение конечно в лоб, это вам для примера. Определяем количество блоков countArr: 7, чтобы их циклом вывести на страницу, в css добавляем класс для блоков color.

Добавляем обработку при клике @click="getInfo($event)". При клике на элемент получаем класс, и находим все элементы с таким классом, в цикле пробегаем и удаляем класс add если он есть. Потом добавляем класс add по блоку по которому кликнули

const app = new Vue({
  el: '#app',
  data() {
    return {
      countArr: 7
    };
  },
  methods: {
    getInfo({target}) {

      let classItem = document.querySelectorAll(`.${target.className}`)
      classItem.forEach((i) => i.classList.contains('add') ? i.classList.remove('add') : '')
      target.classList.add('add')

    }
  }

});
.wrapper {
  gap: 10px;
  display: flex;
}

.color {
  background: #33f;
  width: 100px;
  height: 100px;
}

.add {
  background: #f44336;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>

<div id="app">
  <div class="wrapper">
    <div class="color" v-for="(count, idx) in countArr" :key="idx" @click="getInfo($event)"></div>
  </div>
</div>

→ Ссылка
Автор решения: Alexander

Вот простая реализация того, что вам нужно. Vue создавался для того, чтобы избавить разработчика от явного взаимодействия с DOM. Еще важно отметить, что если вы создаёте радиокнопки на вашем сайте, то по множеству причин создавать их лучше всего с помощью <input type="radio">.

<html>

<head>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
  <style>
    .wrapper { gap: 10px; display: flex; }
    .color { background: #33f; width: 100px; height: 100px;}
    .add { background: #f44336; }
  </style>
</head>

<body>
  <!-- template -->
  <div id="app">
    <div class="wrapper">
      <div
        class="color"
        v-for="(button, idx) in buttons"
        :key="idx"
        :class="{ add: button.clicked }"
        @click="select(idx)"
      >
      </div>
    </div>
  </div>
  <!-- /template -->

  <!-- script -->
  <script>
    new Vue({
      el: '#app',
      data() {
        return {
          buttons: [
            { clicked: false },
            { clicked: false },
            { clicked: false },
            { clicked: false },
            { clicked: false },
          ]
        };
      },
      methods: {
        select(idx) {
          // Обновляем только те объекты, которые нам нужны, а остальные не трогаем - так Vue придется перересовывать меньше элементов
          const currentButton = this.buttons.find((b) => b.clicked) || {};
          currentButton.clicked = false;

          this.buttons[idx].clicked = true;
        }
      }
    });
  </script>
  <!-- /script -->
</body>

</html>

UPD Если вдруг кто-то забыл, можно легко создать массив кнопок любой длинны.

Нужно код:

return {
  buttons: [
    { clicked: false },
    { clicked: false },
    { clicked: false },
    { clicked: false },
    { clicked: false },
  ]
};

На этот:

return {
  buttons: Array.from({ length: 10000 }, () => ({ clicked: false }))
};
→ Ссылка
Автор решения: Pavel Nazarian

const { createApp } = Vue
  createApp({
     data() {
        return {
           activeItem: null,
        }
    }
}).mount('#app')
#app {
  display: flex;
  flex-wrap: wrap;
  gap: 15px;  
}
#app div {
  width: 50px;
  height: 50px;
  border: 1px solid grey;
  cursor: pointer;
}

#app div.active {
  background: blue;
}
<script src="https://unpkg.com/[email protected]/dist/vue.global.prod.js"></script>
<div id="app">
    <div
      v-for="n in 10" 
      :key="n"
      :class="{active: n === activeItem}"
      @click="activeItem = n"
    />         
        
</div>

→ Ссылка