侧边栏收起缩放适配方案

侧边栏收起缩放适配方案

一、问题描述

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 尺寸扩展后会自动按比例分配空间,无需额外调整。
相关推荐
用户7783366132111 小时前
serpbase + Cloudflare R2 边缘持久化实战
前端·人工智能
এ慕ོ冬℘゜1 小时前
jQuery attr() 方法超详细讲解:属性获取、赋值、实战踩坑全解
前端·javascript·jquery
东方小月1 小时前
从零开发一个 Coding Agent(三):EventStream 事件流通道设计与实现
前端·人工智能·后端
程序员黑豆3 小时前
鸿蒙应用开发:Refresh + List 下拉刷新组件使用教程
前端·华为·harmonyos
Hilaku3 小时前
为什么大厂对前端算法要求极高?
前端·javascript·程序员
Tkto3 小时前
我用 WebGL 从「画个点」一路画到「贪吃蛇」
前端
xiaobaoyu3 小时前
前端代码常用规范
前端
xiaobaoyu3 小时前
img,word,excel,pdf文件在线预览
前端
lichenyang4533 小时前
从 H5 到 HarmonyOS:我做了一个 npm + OHPM 双端发布的 ArkWeb JSBridge 框架
前端