Vue 3:在v-for循环内单击按钮时切换类

lyr7nygr  于 2023-03-13  发布在  Vue.js
关注(0)|答案(2)|浏览(263)

我有我的vue 3应用程序,它几乎可以工作。里面有一个v-for循环遍历一个项目数组。这会为数组中的每个项目生成一个很好的列表。在列表中的每个项目上都有一些部分隐藏的文本和一个按钮,用于根据按钮的点击显示所有文本。文本是完全显示还是部分隐藏取决于元素上的css类。
我让它在单击按钮时工作,但这最终会显示所有元素的文本或不显示任何元素,因为它是全局属性被更改。为此,我的代码如下所示:

<script>
const isActive = ref(false);
const toggleAccordion = async () => {
    isActive.value = !isActive.value;

    console.log(isActive.value); //This one changes between false and true correctly
};
</script>

<template>
    <div>
        <div v-for="item in items" :key="item.id">
            <div class="my-class" :class="{ 'is-open': isActive }" v-html="item.details"></div>
        </div>
        <button @click="() => toggleAccordion()">Toggle text</button>
    </div>
</template>

如前所述,上面的代码为循环中的所有元素切换类。
所以我尝试了一些不同的东西,我想我可以让它工作在我的函数和循环中的索引,我尝试了下面的代码:

<script>
    const isActive = ref(false);
    const toggleAccordion = async (i) => {
        isActive[i].value = !isActive[i].value;        
    };
</script>
    
<template>
    <div>
        <div v-for="item in items" :key="item.id">
            <div class="my-class" :class="{ 'is-open': isActive[i] }" v-html="item.details"></div>
        </div>
        <button @click="() => toggleAccordion(i)">Toggle text</button>
    </div>
</template>

但我一定错过了什么地方,因为它没有,我得到控制台错误说:

Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'value')

控制台错误出现在以下行:isActive[i].value = !isActive[i].value;
我也尝试过类似的方法,它不会在控制台中给予任何错误。

<script>
        const isActive = ref(false);
        const toggleAccordion = async (i) => {
            isActive[i] = !isActive[i];        
        };
</script>
        
<template>
    <div>
        <div v-for="item in items" :key="item.id">
            <div class="my-class" :class="{ 'is-open': isActive[i] }" v-html="item.details"></div>
        </div>
        <button @click="() => toggleAccordion(i)">Toggle text</button>
    </div>
</template>

上面的代码实际上改变了isActive[i]的值,但是它没有在代码中的div上切换我的.is-open类。
有人能给我指出正确的方向吗?因为我对代码视而不见,或者肯定错过了什么,或者完全不明白哪里出了问题。
提前非常感谢任何能帮忙的人。

r1zk6ea1

r1zk6ea11#

使用toggleAccordion创建activeMapindex的ale切换。

<script setup>
    const activeMap = reactive({})

    const toggleAccordion = (index) => {
        activeMap[index] = !activeMap[index]
    }
</script>

<template>
<div>
    <div v-for="(item, index) in items" :key="item.id">
        <div class="my-class" :class="{ 'is-open': !!activeMap[index] }" v-html="item.details">
        </div>
        <button @click="() => toggleAccordion(index)">Toggle text</button>
    </div>
</div>
iqxoj9l9

iqxoj9l92#

首先,isActive是一个布尔类型,它内部没有任何属性,所以它会抛出错误"Cannot read properties of undefined (reading 'value')"。您需要将isActive设置为对象,这样它就可以将索引作为属性保存。此外,您需要使用reactive API,这样对isActive[i]等索引的更改在Vue模板中将是React性的。
脚本应该看起来像这样-

<script setup>
import { reactive } from "vue"

const items = [{"details": "First"}, {"details": "Second"}];

const isActive = reactive({});

const toggleAccordion = async (i) => {
  isActive[i] = isActive[i] ? !isActive[i] : true;
}; 
</script>

这里是一个工作演示,试试看.

相关问题