Vue/Bootstrap表格行折叠内嵌编辑表单实现方案咨询
解决方案:行内折叠编辑表单的组件化实现
方案1:通过插槽(Slot)让SortTable支持自定义折叠内容(推荐,复用性最强)
核心思路是让SortTable具备渲染每行下方折叠区域的能力,把编辑表单作为插槽内容由父组件(组件B)提供,SortTable只负责管理折叠状态和传递当前行数据。
步骤1:修改SortTable组件
- 添加响应式数据记录展开的行ID:
<script setup> import { ref } from 'vue' // 存储展开的行ID,支持多行展开(若仅允许单行,改成单个值即可) const expandedRowIds = ref(new Set()) // 点击行时切换折叠状态,同时保留原有点击事件逻辑 const handleRowClick = (row) => { const rowId = row.id // 假设每行有唯一id标识,可根据实际字段调整 if (expandedRowIds.value.has(rowId)) { expandedRowIds.value.delete(rowId) } else { expandedRowIds.value.add(rowId) } emit('clicked', row) } </script>
- 在表格行后添加折叠行插槽:
<template> <table class="table"> <!-- 原有表头、行渲染逻辑保持不变 --> <thead>...</thead> <tbody> <tr v-for="item in srcdata" :key="item.id" @click="handleRowClick(item)"> <td v-for="col in datacolumns" :key="col.key"> <!-- 原有单元格内容渲染逻辑 --> </td> </tr> <!-- 折叠行:根据展开状态显示/隐藏 --> <tr v-for="item in srcdata" :key="`collapse-${item.id}`"> <td :colspan="datacolumns.length"> <div :class="['collapse', expandedRowIds.has(item.id) ? 'show' : '']"> <!-- 插槽传递当前行数据给父组件 --> <slot name="collapse-content" :row="item"></slot> </div> </td> </tr> </tbody> </table> </template>
步骤2:组件B中调用SortTable并传入编辑表单
<template> <SortTable @clicked="itemClicked" :srcdata="itemlist" :datacolumns="[ { key: 'name', name: 'Analyse' }, { key: 'code', name: 'Analysetype', dataformat: plantype }, { key: 'group', name: 'groups', dataformat: abonnentGruppeNavn }, { key: 'id', name: '', link: sletLink, dataformat: (val) => 'delete' }, ]" > <!-- 折叠区域的编辑表单,通过slotProps获取当前行数据 --> <template #collapse-content="{ row }"> <form> <div class="form-group"> <label>名称</label> <input class="form-control" v-model="row.name" /> </div> <div class="form-group"> <label>类型</label> <input class="form-control" v-model="row.code" /> </div> <button type="button" class="btn btn-primary" @click="saveRow(row)">保存</button> <button type="button" class="btn btn-secondary" @click="closeCollapse(row.id)">关闭</button> </form> </template> </SortTable> </template> <script setup> const closeCollapse = (rowId) => { // 调用SortTable的折叠状态切换逻辑,可通过自定义事件实现 // 或在组件B中维护状态(若SortTable支持传入expandedRowIds) } </script>
方案2:状态提升+组件通信(适合无法修改SortTable的场景)
如果不能修改SortTable组件,可将折叠状态放在组件B中维护,通过SortTable的点击事件更新状态,再动态渲染折叠表单。
步骤1:组件B中管理折叠状态
<script setup> import { ref } from 'vue' // 单行展开用单个ID,多行用Set存储 const expandedRowId = ref(null) const itemClicked = (row) => { // 切换折叠状态 expandedRowId.value = expandedRowId.value === row.id ? null : row.id // 原有加载数据逻辑... } </script>
步骤2:联动表格与折叠表单
将表格和折叠表单放在同一容器,通过v-for对应行数据:
<template> <div class="table-wrapper"> <SortTable @clicked="itemClicked" :srcdata="itemlist" :datacolumns="[/* 配置不变 */]" /> <!-- 动态渲染折叠表单,对应每行位置 --> <div v-for="item in itemlist" :key="`form-${item.id}`" class="collapse-wrapper"> <div :class="['collapse', expandedRowId === item.id ? 'show' : '']"> <form> <!-- 编辑表单项,绑定item数据 --> </form> </div> </div> </div> </template> <style scoped> .table-wrapper { position: relative; } .collapse-wrapper { width: 100%; } </style>
关键注意事项
- 复用性保障:方案1通过插槽实现SortTable与表单的解耦,任何需要行内折叠表单的场景都可直接复用SortTable,仅需传入不同的表单内容。
- 折叠状态控制:单行展开用单个变量存储ID,多行展开用Set存储多个ID,按需选择即可。
- 动画兼容:若使用Bootstrap折叠动画,确保正确引入Bootstrap CSS,或用Vue的
<Transition>组件自定义过渡效果。
内容的提问来源于stack exchange,提问作者Kristoffer Boesen
相关产品推荐
相关产品推荐

