name: eng表单标签页化 overview: 将 gw-ui/src/views/slaj/eng 下 10 个 atteng* 属性编辑弹窗内的超长表单,按现有 el-divider 分组改造为 el-tabs 标签页布局,单屏只显示一个分组,解决表单超出屏幕高度的问题。 design: architecture:
framework: vue
styleKeywords:
- Element Plus
- 企业级简洁
- 标签页分组
- 固定底部操作栏
fontSystem:
fontFamily: PingFang SC
heading:
size: 16px
weight: 600
subheading:
size: 14px
weight: 500
body:
size: 14px
weight: 400
colorSystem:
primary:
- "#409EFF"
background:
- "#FFFFFF"
- "#F5F7FA"
text:
- "#303133"
- "#606266"
functional:
- "#409EFF"
- "#67C23A"
- "#F56C6C"
- "#909399"
todos:
工程属性编辑弹窗(10 个 eng 视图)表单字段过多,整体超出屏幕高度,用户希望采用「方案 B:将表单按现有分组拆成标签页(el-tabs)分块显示,单屏只展示一组」来改善。
将各工程编辑弹窗内原本纵向排列、以 el-divider 分隔的长表单,重构为顶部标签切换的分组表单。每个分组(如基本信息、供水参数、时间信息等)对应一个 el-tab-pane,用户点击标签切换查看,弹窗高度不再随字段总数增长。
el-divider 分组改造为 el-tabs + el-tab-pane 结构,保持单个 el-form 不变以保证整体校验/提交有效。el-tab-pane,坐标回写逻辑不变。<script setup>)+ Element Plus(el-dialog / el-form / el-tabs / el-tab-pane)src/assets/styles/index.scss)el-* 组件与 dict-tag、TiandituMapPicker 等自定义组件)仅做「视觉分组」改造:把每个弹窗内的 el-form 内容从「el-divider + 连续 el-row」改为「el-tabs 包裹多个 el-tab-pane」,每个 el-tab-pane 容纳原一个分组的所有 el-row。不拆分 el-form,仍由 proxy.$refs.formRef.validate() 统一校验全部字段(Element Plus 的 el-tab-pane 默认渲染全部面板,字段始终在 DOM 中,跨标签校验正常)。
validate/提交链路,且需重写校验聚合逻辑,风险高。沿用单 form + tabs 是最小侵入且最稳的方案。const activeTab = ref('basic')(name 取首分组标识),在 handleAdd、handleUpdate 中 activeTab.value = 'basic',避免上次停留的标签影响新记录。attengcws/attengres 的单点 mapCoords、attengdike/attengwadi 的起点 startCoords/终点 endCoords,整体移入对应分组 pane,v-model 与 computed 逻辑完全不变。el-dialog 使用 append-to-body 将内容 teleport 到 body,scoped 深度选择器无法命中,故在全局样式 src/assets/styles/index.scss 增加 .el-dialog__body { max-height: 70vh; overflow-y: auto; } 规则(可限定 eng 弹窗 class 以免误伤其他弹窗),保证单标签仍较长时底部按钮始终可见。el-divider:分组标题由 el-tab-pane 的 label 承担,原 el-divider 行移除。prop、rules、API 调用与提交逻辑,仅调整模板包裹结构。el-tab-pane 不使用 lazy,确保校验时字段已挂载。:height="300")保持不变。el-form 之外、el-dialog 的 #footer 模板内,位于标签区下方固定可见。各视图独立改造,结构一致:
flowchart TD
A[el-dialog 750px] --> B[el-form ref=formRef :rules=rules]
B --> C[el-tabs v-model=activeTab]
C --> D[el-tab-pane label=基本信息]
C --> E[el-tab-pane label=XX参数 含地图]
C --> F[el-tab-pane label=时间信息]
B --> G[footer 确定/取消 固定]
提交链路不变:submit() → formRef.validate() → add/update API → 关闭弹窗 → 刷新列表。
gw-ui/src/assets/styles/
└── index.scss # [MODIFY] 增加 eng 编辑弹窗内容区 max-height + overflow-y:auto 全局滚动规则
gw-ui/src/views/slaj/eng/
├── attengcws/index.vue # [MODIFY] 基本信息/供水参数/时间信息 改为 el-tabs;新增 activeTab 并复位;含单点地图
├── attengres/index.vue # [MODIFY] 基本信息/水库参数/时间信息 改为 el-tabs(字段最多);新增 activeTab 并复位;含单点地图
├── attengdike/index.vue # [MODIFY] 基本信息/堤防参数/时间信息 改为 el-tabs;含起点+终点双地图
├── attengwadi/index.vue # [MODIFY] 基本信息/引调水参数/时间信息 改为 el-tabs;含起点+终点双地图
├── attengwaga/index.vue # [MODIFY] 基本信息/水闸参数/时间信息 改为 el-tabs
├── attengsd/index.vue # [MODIFY] 基本信息/淤地坝参数/时间信息 改为 el-tabs
├── attengpust/index.vue # [MODIFY] 基本信息/泵站参数/时间信息 改为 el-tabs
├── attengothe/index.vue # [MODIFY] 基本信息/工程参数/时间信息 改为 el-tabs
├── attenghyst/index.vue # [MODIFY] 基本信息/电站参数/时间信息 改为 el-tabs
└── attengirr/index.vue # [MODIFY] 基本信息/灌区参数/渠道信息/渠系建筑物/时间信息 改为 5 个 el-tab-pane
(不在范围:eng/index.vue 的 base/attr/objEng 弹窗字段较少,无需改造;后端逻辑不变。)
每个视图脚本新增(以 cws 为例,name 按首分组):
const activeTab = ref('basic')
// handleAdd / handleUpdate 开头增加:
activeTab.value = 'basic'
模板骨架(替换原 divider+rows):
<el-tabs v-model="activeTab">
<el-tab-pane label="基本信息" name="basic"> ...原基本信息 el-row... </el-tab-pane>
<el-tab-pane label="供水参数" name="supply"> ...原供水参数 el-row(含地图)... </el-tab-pane>
<el-tab-pane label="时间信息" name="time"> ...原时间信息 el-row... </el-tab-pane>
</el-tabs>
沿用项目既有 Element Plus 企业级简洁风格,不做视觉重构,仅将长表单的「纵向长列表」改为「顶部标签切换的分组表单」。标签栏位于弹窗内容区顶部,分组标题即标签名,单屏只渲染当前分组字段,显著降低纵向高度。
el-tabs,标签左对齐;激活标签高亮(Element Plus 主色),未激活置灰,悬停有轻微背景变化微交互。el-tab-pane 内沿用原 el-row/el-col :span="12" 两列栅格布局,字段间距、label-width(140px) 保持不变;地图组件在对应分组内占满一行。el-dialog 的 #footer 固定显示「确定 / 取消」按钮,始终可见,不随标签切换或内容滚动而消失。弹窗宽度维持 750px(桌面端后台场景),标签在窄屏自动换行;字段两列栅格在极小宽度下由 Element Plus 栅格兜底。