侧边栏收起缩放适配方案

侧边栏收起缩放适配方案

一、问题描述

OverallProcurementDashboardOrderDataPanel 两个大屏看板页面中,使用 CSS scale 缩放方案来适配不同屏幕尺寸。当用户点击收起左侧菜单栏时,会出现以下两个问题:

  1. 竖向滚动条出现:侧边栏收起后可用宽度变大,仅按宽度计算的 scale 值增大,导致缩放后的内容高度超出视口高度,出现竖向滚动条。
  2. 右侧留白 :如果仅用 Math.min(宽度比, 高度比) 限制 scale,缩放后的内容无法填满右侧多出的空间,出现大片空白区域。

二、根本原因分析

原始方案中 scale-wrapper 的尺寸固定为设计稿尺寸(1700×835),缩放计算逻辑如下:

ini 复制代码
原始方案:
  scale = parentWidth / DESIGN_WIDTH   // 仅按宽度计算
  wrapper 尺寸 = 1700 × 835(固定)

问题 1 :侧边栏收起后 parentWidth 变大 → scale 变大 → 835 × scale > parentHeight → 出现竖向滚动条。

问题 2 :若改为 scale = Math.min(sw, sh),侧边栏收起后 sh < swscale 被高度限制 → 1700 × scale < parentWidth → 右侧留白。

三、解决方案

核心思路:同时考虑宽度和高度约束计算 scale,并动态扩展 wrapper 尺寸使缩放后内容恰好填满父容器。

ini 复制代码
新方案:
  sw = parentWidth / DESIGN_WIDTH
  sh = parentHeight / DESIGN_HEIGHT
  scale = Math.min(sw, sh)              // 取较小值,避免任何方向溢出
  wrapper 宽度 = parentWidth / scale     // 动态扩展
  wrapper 高度 = parentHeight / scale    // 动态扩展

原理说明

scale 被高度限制(sh < sw)时:

  • wrapperWidth = parentWidth / scale = parentWidth / sh
  • 缩放后实际宽度 = wrapperWidth × scale = (parentWidth / sh) × sh = parentWidth

即:wrapper 在缩放前被放大,经过 scale 缩小后恰好等于父容器宽度,内部的 grid/flex 布局会自然扩展来填补右侧空白。

四、代码变更

4.1 整体修改文件

文件 修改内容
src/views/wms/OverallProcurementDashboard/index.vue 缩放逻辑 + 外层容器 overflow
src/views/wms/daPing/OrderDataPanel copy.vue 缩放逻辑 + 外层容器 overflow

4.2 JavaScript 逻辑变更

typescript 复制代码
// ===== 修改前 =====
function useWidthScale(containerRef: Ref<HTMLElement | null>) {
  const DESIGN_WIDTH = 1700;
  const DESIGN_HEIGHT = 835;

  const scaleValue = ref(1);
  const { getCollapsed, getRealWidth } = useMenuSetting();

  function updateScale() {
    const el = containerRef.value;
    if (!el) return;
    const parentWidth = el.parentElement?.clientWidth || el.clientWidth;
    const sw = parentWidth / DESIGN_WIDTH;
    scaleValue.value = sw;
  }

  const scaleStyle = computed(() => ({
    transform: `scale(${scaleValue.value})`,
    transformOrigin: 'top left',
    width: `${DESIGN_WIDTH}px`,
    height: `${DESIGN_HEIGHT}px`,
  }));
  // ...
}

// ===== 修改后 =====
function useWidthScale(containerRef: Ref<HTMLElement | null>) {
  const DESIGN_WIDTH = 1700;
  const DESIGN_HEIGHT = 835;

  const scaleValue = ref(1);
  const wrapperWidth = ref(DESIGN_WIDTH);    // 新增:动态宽度
  const wrapperHeight = ref(DESIGN_HEIGHT);  // 新增:动态高度
  const { getCollapsed, getRealWidth } = useMenuSetting();

  function updateScale() {
    const el = containerRef.value;
    if (!el) return;
    // 获取实际内容区域尺寸(父容器)
    const parentWidth = el.parentElement?.clientWidth || el.clientWidth;
    const parentHeight = el.parentElement?.clientHeight || window.innerHeight;
    // 同时基于宽度和高度计算缩放比,取较小值避免内容溢出
    const sw = parentWidth / DESIGN_WIDTH;
    const sh = parentHeight / DESIGN_HEIGHT;
    scaleValue.value = Math.min(sw, sh);
    // 动态扩展包装器尺寸,使缩放后内容恰好填满父容器
    wrapperWidth.value = parentWidth / scaleValue.value;
    wrapperHeight.value = parentHeight / scaleValue.value;
  }

  const scaleStyle = computed(() => ({
    transform: `scale(${scaleValue.value})`,
    transformOrigin: 'top left',
    width: `${wrapperWidth.value}px`,     // 改为动态值
    height: `${wrapperHeight.value}px`,   // 改为动态值
  }));
  // ...
}

4.3 CSS 样式变更

less 复制代码
/* 修改前 */
.dashboard-outer {
  overflow-x: hidden;  /* 只隐藏横向溢出 */
}

/* 修改后 */
.dashboard-outer {
  overflow: hidden;    /* 完全隐藏溢出,禁止滚动条 */
}

五、效果验证

场景 修改前 修改后
侧边栏展开 ✅ 正常 ✅ 正常
侧边栏收起 ❌ 竖向滚动条 + 右侧留白 ✅ 无滚动条,内容填满
窗口缩放 ✅ 正常 ✅ 正常
全屏模式 ✅ 正常 ✅ 正常
内容完整性 ✅ 无隐藏 ✅ 无隐藏

六、注意事项

  1. parentHeight 取值 :优先使用 el.parentElement?.clientHeight,降级使用 window.innerHeightclientHeight 能准确获取父容器的实际可用高度(不含导航栏等)。
  2. 侧边栏动画延迟watch 中已设置 250ms 延迟等待侧边栏动画完成后再重新计算 scale,无需修改。
  3. overflow: hidden:外层容器必须禁止所有方向的溢出,否则动态扩展的 wrapper 可能导致意外滚动条。
  4. 内部布局 :各模块使用 grid1fr 列)或 flex 布局,wrapper 尺寸扩展后会自动按比例分配空间,无需额外调整。
相关推荐
前端粉刷匠3 分钟前
2025 年是 Agent 的,2026 年是 Harness 的——AI 编程 Harness 架构深度解析
前端·人工智能
张元清6 分钟前
React useSessionStorage Hook:刷新不丢、只属于当前标签页的状态 (2026)
前端·javascript·react.js
cindershade12 分钟前
为 TypeScript 项目建立可靠的类型边界:API 响应、表单与第三方库
前端
半仙er15 分钟前
第一周02天 原型与原型链
前端
半仙er16 分钟前
第一周04天Promise 深入与 async / await
前端
fail_to_code16 分钟前
从 Lighthouse 83 到 100:一次 Vue 项目的性能排查实录
前端·人工智能
用户693717500138422 分钟前
DeepSeek 调价正式生效:一夜涨 11 倍,靠低价薅羊毛的日子结束了
前端·人工智能·后端
半仙er28 分钟前
第一周01天:this 指向与 call / apply / bind
前端
小帅不太帅29 分钟前
给大家推荐一个特别好用的专为 AI Agent 打造的最快浏览器
前端·agent·浏览器
半仙er29 分钟前
第一周03天 事件循环与宏任务 / 微任务
前端