fix(styles): 修正车辆调度弹窗表单标签与控件宽度不一致问题
- 修改选择器为后代选择器以适配 avue 表单项的嵌套结构 - 统一弹窗内表单标签宽度,避免 labelWidth: 'auto' 导致控件宽度不一 - 新增全局样式规则,固定标签宽度为 calc(4em + 24px) - 删除用于调试控件宽度的临时文件 cascader-width-check.html - 记录并说明 avue 弹窗宽度调整相关坑点和解决方案
This commit is contained in:
@@ -9,3 +9,10 @@
|
||||
2. `src/styles/element-ui.scss` 增加全局规则 `.vehicle-dispatch-dialog .el-form-item__content > .el-cascader { width:100%; max-width:100% }`。
|
||||
- 自检:dev(2889) `curl /src/styles/element-ui.scss` 与 `/src/option/transportCapacity/vehicle-dispatch.js` 均 200,编译产物含新规则。
|
||||
- 遗留观察:同文件里 `.vehicle-dispatch-page :deep(.avue--detail ...)` 那一批查看态禁用样式,同样因 Teleport 属死规则(未改,待确认是否需要迁到 `.vehicle-dispatch-dialog` 作用域)。
|
||||
|
||||
## 追加修正(同日 20:xx):第一次改完用户反馈「还是没对齐」
|
||||
|
||||
- 原因一:选择器写成了 `.el-form-item__content > .el-cascader`(直接子级)。**avue 表单项在 `el-form-item__content` 与控件之间还有两层包裹 div**(`packages/element-plus/form/index3.js`:content > div > [div|elTooltip] > 控件),必须用后代选择器。已改成 `.vehicle-dispatch-dialog .el-form-item__content .el-cascader`。
|
||||
- 原因二(更隐蔽):option 用 `labelWidth: 'auto'`,**EP 的 auto 是逐项计算**(实测:3 字 54/64px、2 字 40px、4 字无星号 68px、4 字带星号 78px),label 越宽控件可用宽度越小 → 车牌号 input 486px、使用部门 cascader 472px,仍差 14px。已加 `.vehicle-dispatch-dialog .el-form-item__label { flex: 0 0 calc(4em + 24px) !important; width: calc(4em + 24px) !important }`(本弹窗左右两列最长 label 均为 4 汉字)。
|
||||
- 验证方式(可复用):临时在项目根建 `cascader-width-check.html`,Vite 直接服务 → `import './src/option/...'` 用真实 option + `import './src/styles/element-ui.scss'`,挂 avue-crud 并 `mounted(){ this.$refs.crud.rowAdd() }` 弹出真实弹窗;用 agent-browser(`/Users/gxwebsoft/.workbuddy/binaries/node/workspace/node_modules/.bin/agent-browser`)`open` + `eval` 读 DOM 链路与 `getBoundingClientRect`。修完已删除该临时文件。
|
||||
- 结果:全部 label 80px,车牌号 input 与使用部门 cascader 均为 left=732 / width=470 / right=1202,完全一致。
|
||||
|
||||
@@ -14,6 +14,12 @@
|
||||
|
||||
**坑四:avue-crud 弹窗 `append-to-body` 默认 true(`dialog-form3.js`:`validData(tableOption.dialogAppendToBody, true)`),DOM Teleport 到 body。** 于是页面里以页面容器为祖先的 scoped 选择器(`.xxx-page :deep(.yyy)`)**命中不到弹窗内容**,尤其 `el-cascader`(inline-block、宽度按内容收缩,不像 `el-input`/`el-autocomplete` 有 `--el-input-width:100%` 兜底)会明显比同行 input 窄。修法:option 里配 `dialogCustomClass: 'xxx-dialog'`,规则写到 `src/styles/element-ui.scss` 的 `.xxx-dialog ...`(项目既有约定,10+ 处同款);或把基准类放在 **Teleport 内部元素**上(如 ship.vue 的 `.ship-form` 挂在 el-form 上,自身带 scope 属性,照样生效)。
|
||||
|
||||
**坑五:avue 表单项控件不是 `.el-form-item__content` 的直接子级。** `form/index3.js` 渲染为 `content > div > [div|elTooltip] > 控件`,所以 `.el-form-item__content > .el-cascader` 这类**直接子级选择器对 avue 表单全部失效**(手写 `<el-form-item>` 才生效),一律用后代选择器。
|
||||
|
||||
**坑六:`labelWidth: 'auto'` 在 Element Plus 里逐项计算,不是全表单共享。** 实测同一弹窗:3 字 54/64px、2 字 40px、4 字 68px、4 字带必填星号 78px;label 越宽 → 控件可用宽度越小,同级控件宽度就不一致(车牌号 input 486 vs 使用部门 cascader 472)。要让同一行控件等宽必须统一 label 宽度:`.xxx-dialog .el-form-item__label { flex: 0 0 calc(Nem + 24px) !important; width: calc(Nem + 24px) !important }`(N=本列最长汉字数,与 ship.vue、`.dialog-form--carded` 同款)。
|
||||
|
||||
**验证 avue 弹窗 DOM/宽度的可复用办法:** 项目根建临时 html(Vite 直接服务)→ 引真实 option 与 `src/styles/element-ui.scss`,挂 avue-crud 并 `mounted(){ this.$refs.crud.rowAdd() }` 弹出真弹窗;用 `agent-browser`(`/Users/gxwebsoft/.workbuddy/binaries/node/workspace/node_modules/.bin/agent-browser`)`open` + `eval` 读 DOM 链路与 `getBoundingClientRect`,用完删文件。
|
||||
|
||||
**坑三:路由表重复定义 → 内容区整页空白(2026-09-18)。** `/business/contract-manage/detail` 在 `router/views/index.js` 定义两次、子路由同名 `合同详情`。重名 `addRoute` 会 `removeRoute(name)` 移除旧子记录,但**不从父记录 children 里摘除**,第一条 Layout 壳记录留在 matcher 且靠前 → `resolve()` 命中它 → `$route.matched.length === 1` → 二级 router-view 无匹配 → 侧栏/标签正常但内容空白。修法:删重复定义。排查:扫「顶层 path + 首个子路由 name」重复项。
|
||||
|
||||
## 样式硬规则
|
||||
|
||||
@@ -1,84 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title>cascader width check</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
<script type="module">
|
||||
import { createApp, h, ref, resolveComponent } from 'vue';
|
||||
import ElementPlus from 'element-plus';
|
||||
import 'element-plus/dist/index.css';
|
||||
import Avue from '@smallwei/avue';
|
||||
import '@smallwei/avue/lib/index.css';
|
||||
import './src/styles/element-ui.scss';
|
||||
|
||||
const option = {
|
||||
dialogCustomClass: 'vehicle-dispatch-dialog',
|
||||
labelPosition: 'right',
|
||||
labelWidth: 'auto',
|
||||
addBtn: false,
|
||||
editBtn: false,
|
||||
delBtn: false,
|
||||
viewBtn: false,
|
||||
selection: false,
|
||||
column: [
|
||||
{ label: '车牌号', prop: 'plateNo', formslot: true, span: 12 },
|
||||
{ label: '使用部门', prop: 'useDepartment', formslot: true, span: 12 },
|
||||
],
|
||||
};
|
||||
|
||||
const tree = [
|
||||
{ id: 1, title: '桂物物流集团', children: [{ id: 2, title: '广西桂物物流服务集团有限公司' }] },
|
||||
];
|
||||
|
||||
const Demo = {
|
||||
data() {
|
||||
return { option, form: {}, data: [], page: { currentPage: 1, pageSize: 10, total: 0 } };
|
||||
},
|
||||
mounted() {
|
||||
this.$nextTick(() => this.$refs.crud.rowAdd());
|
||||
},
|
||||
render() {
|
||||
const crud = resolveComponent('avue-crud');
|
||||
return h(
|
||||
crud,
|
||||
{
|
||||
ref: 'crud',
|
||||
modelValue: this.form,
|
||||
'onUpdate:modelValue': v => (this.form = v),
|
||||
option: this.option,
|
||||
data: this.data,
|
||||
},
|
||||
{
|
||||
'plateNo-form': () =>
|
||||
h(resolveComponent('el-autocomplete'), {
|
||||
modelValue: this.form.plateNo,
|
||||
'onUpdate:modelValue': v => (this.form.plateNo = v),
|
||||
placeholder: '请选择车牌号',
|
||||
fetchSuggestions: (q, cb) => cb([]),
|
||||
}),
|
||||
'useDepartment-form': () =>
|
||||
h(resolveComponent('el-cascader'), {
|
||||
modelValue: this.form.useDepartment,
|
||||
'onUpdate:modelValue': v => (this.form.useDepartment = v),
|
||||
options: tree,
|
||||
props: { label: 'title', value: 'id', children: 'children', checkStrictly: true },
|
||||
clearable: true,
|
||||
filterable: true,
|
||||
placeholder: '请选择使用部门',
|
||||
}),
|
||||
}
|
||||
);
|
||||
},
|
||||
};
|
||||
|
||||
const app = createApp(Demo);
|
||||
app.use(ElementPlus);
|
||||
app.use(Avue);
|
||||
app.mount('#app');
|
||||
window.__app = app;
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -665,6 +665,15 @@
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
// 车辆调度弹窗 label 宽度统一:option 用 labelWidth: 'auto' 时 label 宽度随字数变化
|
||||
// (3 字 64px / 2 字 40px / 4 字带星号 78px),控件可用宽度随之变化,
|
||||
// 于是同一行两列控件宽度不一致(如车牌号 486px vs 使用部门 472px)。
|
||||
// 本弹窗左右两列最长 label 均为 4 个汉字(所属组织 / 使用部门 / 申请时间),故统一按 4em + 24px 取宽。
|
||||
.vehicle-dispatch-dialog .el-form-item__label {
|
||||
flex: 0 0 calc(4em + 24px) !important;
|
||||
width: calc(4em + 24px) !important;
|
||||
}
|
||||
|
||||
// 过程配置新增/编辑/查看弹窗(手写 el-dialog,参照 vehicle/credit-score-quantification):
|
||||
// 灰底弹窗体(全站 .el-dialog__body 已统一)内堆叠 <section-card> 分组白卡,
|
||||
// 卡间 12px 间距由 section-card 自身 margin-bottom 保证,与项目其他弹窗风格统一
|
||||
|
||||
Reference in New Issue
Block a user