我使用Vue与Nuxt 2,并在我的自定义手风琴组件有问题。
我想一次拉一架手风琴。但实际上发生的是,如果我点击第一个手风琴链接,第一个链接(手风琴)的主体正在打开。而没有关闭第一个,如果我打开第二个环节(手风琴),第二个手风琴身体也打开。我想避免这样做。如果我想打开其他手风琴,打开的手风琴应该先关闭。那么,我如何在不使用任何库的情况下,以vue方式实现这一点。
手风琴切换过程:,我使用ACTIVE值来切换手风琴,方法是在锚标记上添加aria-expended = "true"。同时,我正在显示或隐藏基于accordion-item-body的ACTIVE值。
我的组件手风琴:
<template>
<div id="accordion" ref="accordion" class="accordion">
<slot />
</div>
</template>
<script lang="ts">
import Vue from "vue"
import { props } from "./props"
export default Vue.extend({
name: "Accordion",
props,
created() {
this.$nuxt.$off("eventName")
this.$nuxt.$on("eventName", ($event: any) => this.toggleActive($event))
},
methods: {
toggleActive(e: any) {
console.log(e)
},
},
})
</script>我的AccordionItem组件:
<template>
<div class="accordion-item" role="tab">
<div class="accordion-item-header">
<a
:aria-expanded="active"
@click.prevent=";(active = !active), $nuxt.$emit('eventName', active)"
>
{{ title }}
<span
class="material-icons"
>
expand_more
</span>
</a>
</div>
<transition name="accordion">
<div v-show="active" class="accordion-item-body" role="tabpanel">
<slot />
</div>
</transition>
</div>
</template>
<script lang="ts">
import Vue from "vue"
export default Vue.extend({
name: "AccordionItem",
props: {
title: {
type: String,
required: true,
},
id: {
type: String,
required: true,
},
},
data() {
return {
active: false,
}
},
})
</script>手风琴和在父母中的AccordionItem用法:
<Accordion :items="items">
<AccordionItem
v-for="item in items"
:id="item.id"
:key="item.id"
:title="item.title"
>
<div v-html="item.description"></div>
</AccordionItem>
</Accordion>发布于 2022-04-28 13:31:24
这里有一个简单而有效的解决方案(当然,我没有实现样式设计,但功能运行得很好)。
包装器
<template>
<div>
<accordion
v-for="(item, index) in list"
:key="item.id"
:item="item"
:active-index="currentlyActiveIndex"
:item-index="index"
@update:itemIndex="currentlyActiveIndex = $event"
></accordion>
</div>
</template>
<script>
export default {
name: 'AccordionList',
data() {
return {
list: [
{ id: 1, name: 'hello' },
{ id: 2, name: 'world' },
{ id: 3, name: 'swag' },
],
currentlyActiveIndex: null,
}
},
}
</script>Accordion.vue
<template>
<div>
<button @click="updateIndex">get this index: {{ itemIndex }}</button>
<span v-show="activeIndex === itemIndex">{{ item.name }}</span>
</div>
</template>
<script>
export default {
name: 'Accordion',
props: {
item: {
type: Object,
default: () => {},
},
activeIndex: {
type: Number,
default: null,
},
itemIndex: {
type: Number,
default: null,
},
},
methods: {
updateIndex() {
console.log('index updated:', this.itemIndex)
this.$emit('update:itemIndex', this.itemIndex)
},
},
}
</script>这也可以通过类似{ id: 1, name: 'hello', isActive: false }这样的方法来实现,但这两种方法在这里都是有效的。
PS:我也不知道如何使用TS,但我相信你自己也能理解这个部分(我猜这里不是阻断剂)。
https://stackoverflow.com/questions/72042753
复制相似问题