Vue3实现折叠面板
Vue3 实现一个折叠面板组件
折叠面板(Accordion)是一种常见的 UI 组件,通常用于展示内容列表,用户可以点击标题展开或折叠内容。
一、需求分析
实现一个 Vue3 的折叠面板组件,具备以下功能:
- 折叠和展开:点击标题可以展开内容,再次点击可以折叠内容。
- 支持多个面板:可以同时展开多个面板。
- 支持单个面板展开:可以设置为“手风琴模式”,即每次只能展开一个面板。
二、实现步骤
1. 创建折叠面板组件
在 src/components
文件夹下创建一个名为 Accordion.vue
的组件。
Accordion.vue
<template><div class="accordion"><divv-for="(item, index) in items":key="index"class="accordion-item"><!-- 标题 --><divclass="accordion-header"@click="togglePanel(index)"><span>{{ item.title }}</span><span>{{ isOpen(index) ? '▲' : '▼' }}</span></div><!-- 内容 --><divv-show="isOpen(index)"class="accordion-content"><p>{{ item.content }}</p></div></div></div>
</template><script>
import { ref } from 'vue';export default {name: 'Accordion',props: {items: {type: Array,required: true,},singleOpen: {type: Boolean,default: false, // 是否为手风琴模式},},setup(props) {// 当前打开的面板索引const openPanels = ref([]);// 切换面板状态const togglePanel = (index) => {if (props.singleOpen) {// 手风琴模式:只允许一个面板打开 openPanels是否包含?包含则清空数组,不包含则加上openPanels.value = openPanels.value.includes(index) ? [] : [index];} else {// 普通模式:允许多个面板同时打开//使用 includes 方法检查索引是否在 openPanels 中,如果在则移除,否则添加。if (openPanels.value.includes(index)) {openPanels.value = openPanels.value.filter((i) => i !== index);} else {openPanels.value.push(index);}}};// 判断面板是否打开const isOpen = (index) => {return openPanels.value.includes(index);};return {togglePanel,isOpen,};},
};
</script><style scoped>
.accordion {border: 1px solid #ccc;border-radius: 5px;overflow: hidden;
}.accordion-item {border-bottom: 1px solid #ddd;
}.accordion-header {display: flex;justify-content: space-between;align-items: center;padding: 10px;background-color: #f5f5f5;cursor: pointer;
}.accordion-header:hover {background-color: #eaeaea;
}.accordion-content {padding: 10px;background-color: #fff;border-top: 1px solid #ddd;
}
</style>
2. 使用组件
在 src/App.vue
中引入并使用这个组件:
<template><div><h1>Vue3 折叠面板组件</h1><!-- 普通模式:允许多个面板同时打开 --><Accordion :items="accordionItems" /><h2 style="margin-top: 20px;">手风琴模式</h2><!-- 手风琴模式:每次只能打开一个面板 --><Accordion :items="accordionItems" :singleOpen="true" /></div>
</template><script>
import Accordion from './components/Accordion.vue';export default {components: {Accordion,},data() {return {accordionItems: [{ title: '面板 1', content: '这是面板 1 的内容' },{ title: '面板 2', content: '这是面板 2 的内容' },{ title: '面板 3', content: '这是面板 3 的内容' },],};},
};
</script>
三、功能解析
1. 折叠和展开
- 核心逻辑
- 使用
openPanels
数组记录当前打开的面板索引。 - 点击标题时,检查索引是否在
openPanels
中,如果在则移除,否则添加。
- 使用
- 手风琴模式
- 如果
singleOpen
为true
,每次点击时只允许一个面板打开。
- 如果
2. 动态内容
- 支持动态传入数据
- 使用
props
接收items
数据,数据格式为数组,每个元素包含title
和content
。
- 使用
3. 样式和交互
- 样式
- 使用
v-show
控制内容的显示和隐藏。 - 添加鼠标悬停效果,让标题在鼠标经过时有背景变化。
- 使用
- 交互
- 在标题右侧显示箭头图标,指示当前面板的状态(展开或折叠)。
四、效果展示
运行项目后,你会看到两个折叠面板:
- 普通模式:允许同时展开多个面板。
- 手风琴模式:每次只能展开一个面板。
点击标题可以展开或折叠内容,右侧的箭头会根据状态变化。
五、总结
文章实现了一个简单的 Vue3 折叠面板组件,支持普通模式和手风琴模式。这个组件的核心逻辑非常简单,主要依赖数组操作和条件判断。可以根据自己的需求进一步扩展,比如:
- 添加动画效果,让展开和折叠更流畅。
- 支持嵌套面板,实现更复杂的结构。