Как задать класс по клику во VueJS
Есть вот такой код:
<div class="game__wrapper">
<div v-for="(_, x) in 3" :key="x" class="row">
<button v-for="(_, y) in 3" :key="y" class="square" @click="move(x, y)">
{{ squares[x][y] }}
</button>
</div>
</div>
сама функция
const move = (x, y) => {
if (winner.value) return
squares.value[x][y] = player.value
player.value = player.value === 'O' ? 'X' : 'O'
}
Создается 9 кнопок, мне нужно, чтоб при нажатии на какую-то к этой кнопке добавлялся класс 'square--lock' Просидел весь день, ничего не придумал. Спасибо за помощь!) UPD: использую Vue Composition API
Ответы (2 шт):
Спустя 2 дня, я всё-таки нашел способ. Да, он костыльный, я уверен, что можно сделать что-то лучше, но:
let squaresArr = squares.value.flat()
let domSquares = document.querySelectorAll('.square')
for (let i = 0; i < squaresArr.length; i++) {
if(squaresArr[i] !== ''){
domSquares[i].classList.add('squareLock')
}
}
Этот код я добавил в функцию move. Таким образом, в переменной squaresArr хранится массив со значениями всех 9-ти кнопок. Перебирая массив мы получаем индексы тех кнопок, которые ещё не нажаты. Также была создана переменная domSquares , хранящая массив этих же кнопок, но уже из DOM дерева. В итоге, элемент в domSquares с этим индексом нам и нужен.
const app = new Vue({
el: "#app",
data() {
return {
table: [
[
0, 0, 0
],
[
0, 0, 0
],
[
0, 0, 0
],
],
activeIndex: {
x: -1,
y: -1
}
};
},
methods: {
tableClick(x, y) {
this.activeIndex.x = x
this.activeIndex.y = y
},
},
});
.row {
width: 30px;
height: 30px;
border: 1px solid;
}
.table {
display: flex;
}
.active {
background: red
}
<script src="https://cdn.jsdelivr.net/npm/[email protected]"></script>
<div id="app">
<div class="table">
<div class="column" v-for="(row, x) in table">
<div class="row" v-for="(value, y) in row" :class="activeIndex.x === x && activeIndex.y === y ? 'active': ''"
@click="tableClick(x,y)" :key="x+''+y">
</div>
</div>
</div>
</div>
Если Вам надо только добавить класс, то можно так:
const app = new Vue({
el: "#app",
data() {
return {
table: [
[
0, 0, 0
],
[
0, 0, 0
],
[
0, 0, 0
],
],
};
},
methods: {
tableClick(event) {
event.target.classList.add('active')
},
},
});
.row {
width: 30px;
height: 30px;
border: 1px solid;
}
.table {
display: flex;
}
.active {
background: red
}
<script src="https://cdn.jsdelivr.net/npm/[email protected]"></script>
<div id="app">
<div class="table">
<div class="column" v-for="(row, x) in table">
<div class="row" v-for="(value, y) in row"
@click="tableClick(x, y)" :key="x+''+y">
</div>
</div>
</div>
</div>
Или так
const app = new Vue({
el: "#app",
data() {
return {
table: [
[
0, 0, 0
],
[
0, 0, 0
],
[
0, 0, 0
],
],
};
},
methods: {
tableClick(row, y) {
row.splice(y,1,1) // splice - для реактивности, но во Vue3, наверное, не будет этой проблемы
},
},
});
.row {
width: 30px;
height: 30px;
border: 1px solid;
}
.table {
display: flex;
}
.active {
background: red
}
<script src="https://cdn.jsdelivr.net/npm/[email protected]"></script>
<div id="app">
<div class="table">
<div class="column" v-for="(row, x) in table">
<div class="row" v-for="(value, y) in row" :class="value ? 'active': ''"
@click="tableClick(row,y)" :key="x+''+y">
</div>
</div>
</div>
</div>