To create an exapndable list where clicking an item shows its content while hiding others, implement a Vue component with state management for tracking active items and toggle status.
Template Structure
<div class="faq-section">
<h3>Frequently Asked Questions</h3>
<ul class="faq-list">
<div v-for="(question, idx) in questions"
:class="{'active-item': activeIndex === idx}">
<li @click="toggleQuestion(question.id, idx)">
<span class="question-title">{{ question.title }}</span>
<span class="toggle-icon">{{ activeIndex === idx ? '−' : '+' }}</span>
</li>
<div class="answer-content" v-if="activeIndex === idx">
<p v-for="(answer, ansIdx) in currentAnswers"
:key="ansIdx">
{{ ansIdx + 1 }}. {{ answer.content }}
</p>
</div>
</div>
</ul>
</div>
Component Logic
export default {
data() {
return {
activeIndex: -1,
toggleFlag: false,
clickHistory: [],
currentAnswers: []
}
},
methods: {
toggleQuestion(qId, idx) {
this.clickHistory.push(idx);
const lastClick = this.clickHistory[this.clickHistory.length - 1];
const previousClick = this.clickHistory[this.clickHistory.length - 2];
if (lastClick === previousClick && this.toggleFlag) {
this.activeIndex = -1;
} else {
this.activeIndex = idx;
this.fetchAnswers(qId);
}
this.toggleFlag = !this.toggleFlag;
},
fetchAnswers(questionId) {
const requestData = {
parentId: this.parentId,
questionType: questionId
};
getQuestionAnswers(requestData).then(response => {
this.currentAnswers = response.data;
});
}
}
}
CSS Styling
.active-item {
background-color: #f5f5f5;
border-left: 3px solid #007bff;
}
.question-title {
font-weight: bold;
color: #333;
}
.toggle-icon {
float: right;
font-weight: bold;
color: #666;
}
.answer-content {
padding: 10px;
background-color: #fff;
border-top: 1px solid #eee;
}
The component tracks the active item index and toggle state. When a user clicks a list item, it checks if the same item was clicked consecutive with the toggle flag active, collapsing the content if both conditions are met. Otherwise, it expands the clicked item and fetches related data.