I have loop as below:
data: {
show: false
}
.test {
hight: 10px;
background-color: red;
}
.test2 {
hight: 15px;
}
<script src=".5.17/vue.js"></script>
<div v-for="value in data" :key="value.id">
<div class="test" v-bind:class="{ test2: show }" v-on:click="show = !show">
</div>
</div>
Now if I click any div
, it will be changed all the divs's height from 15 to 10 or 10 to 15.
However, I want to change the only the div
that I clicked. How can I do this?
I have loop as below:
data: {
show: false
}
.test {
hight: 10px;
background-color: red;
}
.test2 {
hight: 15px;
}
<script src="https://cdnjs.cloudflare./ajax/libs/vue/2.5.17/vue.js"></script>
<div v-for="value in data" :key="value.id">
<div class="test" v-bind:class="{ test2: show }" v-on:click="show = !show">
</div>
</div>
Now if I click any div
, it will be changed all the divs's height from 15 to 10 or 10 to 15.
However, I want to change the only the div
that I clicked. How can I do this?
4 Answers
Reset to default 3You need to add show
variable for each element:
new Vue({
el: "#app",
data: {
show: [],
items: []
},
created() {
fakeFetch().then((items) => {
this.items = items;
this.show = this.items.map(() => false);
});
},
methods: {
isShown(i) {
return this.show[i]
},
changeShow(i) {
Vue.set(this.show, i, !this.show[i]);
}
}
})
function fakeFetch() {
return new Promise((resolve, reject) => {
let count = Math.floor(Math.random() * 20) + 1;
let result = [];
for (let i = 0; i < count; i++) {
result.push({ text: Math.random() });
}
resolve(result);
})
}
.test {
height:10px;
background-color: red;
margin: 10px;
}
.test2 {
height: 35px;
}
<script src="https://cdn.jsdelivr/npm/[email protected]/dist/vue.js"></script>
<div id="app">
<h2>Items:</h2>
<div
class="test"
:class="{ test2: isShown(index) }"
@click="changeShow(index)"
v-for="(item,index) in items" :key="index">
</div>
</div>
P.S. To avoid this routine with show
array you can define each element as ponent and switch visibility inside it with single variable show
.
You can simply set active variable, and bind class if it's equal to current button index
<div v-for="(value, index) in data" :key="index">
<div class="some-class" :class="{'active-class': index === active}" @click="active=index"></div>
</div>
.....
data: function () {
return {
active: undefined
}
}
You are using only one variable to control the class of every item, to enable more specific changes, you should have a variable for each item.
If you are in control of the data you are displaying, you can declare it in a way like this
data: {
items: [{id: 1, visible: false},
{id: 2, visible: false},
{id: 3, visible: false}]
}
and change the visible attribute instead of a global show
variable.
If you are not, you may want to consider building it through a puted property
You can check this solution on this codepen https://codepen.io/anon/pen/ejmdPX?editors=1111
You could use a method to set the class you want.
If you run v-on:click="myFunc()"
you get an event that you can use to make changes to the specific element.
methods: {
myFunc (event) {
event.target.classList.toggle("test2")
}
}