在 v-for items 内部切换会影响整个列表,如何让每个切换只影响包含的列表项?
Toggle inside v-for items affects the entire list, how can I make the each toggle affect only the containing list item?
我正在使用 v-for 循环制作项目列表。在循环的每个项目中,都有带有显示描述文本的单击事件方法的按钮。
当我点击按钮时,它应该只在它自己的项目内切换,但它会影响 v-for 列表中的所有元素。
那么,如何制作一个只影响它自己的项目的切换方法?
<template>
<div>
<div v-for="item in items" :class="{ activeclass: isActive }">
<div class="item-text">
{{item.text}}
</div>
<button @click="toggle()">show</button>
<div v-show="isActive" class="item-desc">
{{item.desc}}
</div>
</div>
</div>
</template>
<script>
export default {
data () {
return {
items: [
{
text: 'Foo',
desc: 'The Array.from() method creates a new Array instance from an array-like or iterable object.',
},
{
text: 'Bar',
desc: 'The Array.from() method creates a new Array instance from an array-like or iterable object.',
}
],
isActive: false
}
},
methods: {
toggle: function () {
this.isActive = !this.isActive;
}
},
}
</script>
如果要显示说明,您可以在列表中的每个项目上添加 属性:
<template>
<ul>
<li v-for="item in items" :class="{ activeclass: item.isActive }">
<div class="item-text">
{{ item.text }}
</div>
<button @click="toggle(item)">show</button>
<div v-show="item.isActive" class="item-desc">
{{ item.desc }}
</div>
</li>
</ul>
</template>
<script>
export default {
data () {
return {
items: [
{
isActive: false,
text: 'Foo',
desc: 'The Array.from() method creates a new Array instance from an array-like or iterable object.',
},
{
isActive: false,
text: 'Bar',
desc: 'The Array.from() method creates a new Array instance from an array-like or iterable object.',
}
],
}
},
methods: {
toggle: function (item) {
item.isActive = !item.isActive;
}
},
}
</script>
或者,您可以将 li
提取到单独的组件中。
正如@Nora 所说,您可以(并且可能应该)为每个列表项创建一个单独的组件,因此您将拥有一个接受 item
作为道具的组件,然后每个组件都可以拥有自己的组件isActive
标志,使标记保持整洁:
分量:
Vue.component('toggle-list-item', {
template: '#list-item',
props: ['item'],
methods: {
toggle() {
this.isActive = !this.isActive;
}
},
data() {
return {
isActive: false
}
},
})
标记
现在您只需将组件放入 v-for
:
<div id="app">
<div v-for="item in items">
<toggle-list-item :item="item"></toggle-list-item>
</div>
</div>
这是 JSFiddle:https://jsfiddle.net/w10qx0dv/
我运行遇到了同样的问题,我是这样解决的。
我获取了一个数组并推送了点击项目的索引,并根据数组中可用的索引,我们现在可以显示或隐藏该元素。
<template>
<div>
<div v-for="(item,i) in items">
<div class="item-text">
{{ item.text }}
</div>
<button @click="toggle(i)">show</button>
<div v-show="clickedItems.includes(i)" class="item-desc">
{{ item.desc }}
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
items: [
{
text: 'Foo',
desc: 'The Array.from() method creates a new Array instance from an array-like or iterable object.',
},
{
text: 'Bar',
desc: 'The Array.from() method creates a new Array instance from an array-like or iterable object.',
}
],
clickedItems:[]
}
},
methods: {
toggle() {
if (this.clickedItems.includes(i)) {
this.clickedItems.splice(this.clickedItems.indexOf(i), 1);
} else {
this.clickedItems.push(i);
}
}
},
}
</script>
我正在使用 v-for 循环制作项目列表。在循环的每个项目中,都有带有显示描述文本的单击事件方法的按钮。 当我点击按钮时,它应该只在它自己的项目内切换,但它会影响 v-for 列表中的所有元素。
那么,如何制作一个只影响它自己的项目的切换方法?
<template>
<div>
<div v-for="item in items" :class="{ activeclass: isActive }">
<div class="item-text">
{{item.text}}
</div>
<button @click="toggle()">show</button>
<div v-show="isActive" class="item-desc">
{{item.desc}}
</div>
</div>
</div>
</template>
<script>
export default {
data () {
return {
items: [
{
text: 'Foo',
desc: 'The Array.from() method creates a new Array instance from an array-like or iterable object.',
},
{
text: 'Bar',
desc: 'The Array.from() method creates a new Array instance from an array-like or iterable object.',
}
],
isActive: false
}
},
methods: {
toggle: function () {
this.isActive = !this.isActive;
}
},
}
</script>
如果要显示说明,您可以在列表中的每个项目上添加 属性:
<template>
<ul>
<li v-for="item in items" :class="{ activeclass: item.isActive }">
<div class="item-text">
{{ item.text }}
</div>
<button @click="toggle(item)">show</button>
<div v-show="item.isActive" class="item-desc">
{{ item.desc }}
</div>
</li>
</ul>
</template>
<script>
export default {
data () {
return {
items: [
{
isActive: false,
text: 'Foo',
desc: 'The Array.from() method creates a new Array instance from an array-like or iterable object.',
},
{
isActive: false,
text: 'Bar',
desc: 'The Array.from() method creates a new Array instance from an array-like or iterable object.',
}
],
}
},
methods: {
toggle: function (item) {
item.isActive = !item.isActive;
}
},
}
</script>
或者,您可以将 li
提取到单独的组件中。
正如@Nora 所说,您可以(并且可能应该)为每个列表项创建一个单独的组件,因此您将拥有一个接受 item
作为道具的组件,然后每个组件都可以拥有自己的组件isActive
标志,使标记保持整洁:
分量:
Vue.component('toggle-list-item', {
template: '#list-item',
props: ['item'],
methods: {
toggle() {
this.isActive = !this.isActive;
}
},
data() {
return {
isActive: false
}
},
})
标记
现在您只需将组件放入 v-for
:
<div id="app">
<div v-for="item in items">
<toggle-list-item :item="item"></toggle-list-item>
</div>
</div>
这是 JSFiddle:https://jsfiddle.net/w10qx0dv/
我运行遇到了同样的问题,我是这样解决的。 我获取了一个数组并推送了点击项目的索引,并根据数组中可用的索引,我们现在可以显示或隐藏该元素。
<template>
<div>
<div v-for="(item,i) in items">
<div class="item-text">
{{ item.text }}
</div>
<button @click="toggle(i)">show</button>
<div v-show="clickedItems.includes(i)" class="item-desc">
{{ item.desc }}
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
items: [
{
text: 'Foo',
desc: 'The Array.from() method creates a new Array instance from an array-like or iterable object.',
},
{
text: 'Bar',
desc: 'The Array.from() method creates a new Array instance from an array-like or iterable object.',
}
],
clickedItems:[]
}
},
methods: {
toggle() {
if (this.clickedItems.includes(i)) {
this.clickedItems.splice(this.clickedItems.indexOf(i), 1);
} else {
this.clickedItems.push(i);
}
}
},
}
</script>