先看效果

组件代码
<template>
<div class="accordion">
<div
v-for="(item, index) in items" :key="index" class="accordion-item"
:class="{ 'is-active': activeIndices.includes(index) }"
>
<div class="accordion-header" @click="toggleItem(index)">
{{ item.title }}
<span class="accordion-icon">{{ activeIndices.includes(index) ? '−' : '+' }}</span>
</div>
<!-- 这里利用 Array.includes() 方法来判断是否需要展开 -->
<div class="accordion-content" v-show="activeIndices.includes(index)">
{{ item.content}}
</div>
</div>
</div>
</template>
<script setup>
import { ref } from 'vue'
const props = defineProps({
data: {
required:true,
type: Array,
default: () => [ ]
},
accordion: {
type: Boolean,
default:false,
}
})
const items = ref(props.data)
const activeIndices = ref([]);
const toggleItem = (index) => {
const position = activeIndices.value.indexOf(index);
if (position > -1) {
activeIndices.value.splice(position, 1);
} else {
if (props.accordion && activeIndices.value.length > 0) {
activeIndices.value.splice(0)
}
activeIndices.value.push(index);
}
};
</script>
<style scoped>
.accordion {
width: 100%;
max-width: 600px;
margin: 0 auto;
font-family: Arial, sans-serif;
}
.accordion-item {
border: 1px solid #ddd;
border-radius: 4px;
margin-bottom: 8px;
overflow: hidden;
}
.accordion-header {
padding: 12px 16px;
background-color: #f5f5f5;
cursor: pointer;
display: flex;
justify-content: space-between;
align-items: center;
font-weight: bold;
}
.accordion-header:hover {
background-color: #e9e9e9;
}
.accordion-icon {
font-size: 18px;
}
.accordion-content {
padding: 16px;
background-color: white;
border-top: 1px solid #eee;
}
.is-active .accordion-header {
background-color: #979797;
}
</style>
使用组件
<accordion :data="data" :accordion="true"></accordion>
import accordion from './accordion.vue'
const data= [
{title:"标题1",main:"内容1"},
{title:"标题2",main:"内容2"},
{title:"标题3",main:"内容3"},
{title:"标题4",main:"内容4"},
]