Arco Design Layout 中使用 ResizeBox 实现可拖拽侧边栏

Arco Design Layout 中使用 ResizeBox 实现可拖拽侧边栏

问题

a-layout-sider 虽然有 width 属性可以设置宽度,但没有拖拽事件 来动态调整宽度。直接使用 a-resize-box 替换会导致布局混乱。

解决方案

核心要点 :必须使用 <a-layout :has-sider="true"> 包裹 a-resize-box

vue 复制代码
<a-layout :has-sider="true">
  <a-resize-box
    :directions="['right']"
    :width="sidebarWidthImmediate"
    @moving="handleSidebarResize"
    @moving-end="handleSidebarResizeEnd"
  >
    <div>侧边栏内容</div>
  </a-resize-box>
  <a-layout-content>
    主内容区
  </a-layout-content>
</a-layout>

性能优化:双变量设计

问题

如果只用一个变量,拖拽过程中会频繁触发子组件更新和计算属性重新计算,导致卡顿。

方案

使用两个变量分离视觉反馈和数据传递:

typescript 复制代码
// 视觉反馈变量:高频更新,只影响 ResizeBox
const sidebarWidthImmediate = ref(200)

// 数据传递变量:低频更新,用于子组件和计算属性
const sidebarWidth = ref(200)

function handleSidebarResize(size: { width: number; height: number }) {
  // 拖拽过程中:只更新视觉反馈变量
  sidebarWidthImmediate.value = Math.max(minSidebarWidth, size.width)
}

function handleSidebarResizeEnd() {
  // 拖拽结束时:同步数据传递变量,触发一次子组件更新
  sidebarWidth.value = sidebarWidthImmediate.value
}

性能对比

方案 拖拽时子组件渲染 性能表现
单变量 高频(每秒数十次) ❌ 卡顿
双变量 低频(结束时1次) ✅ 流畅

完整示例

vue 复制代码
<template>
  <a-layout>
    <a-layout-header>Header</a-layout-header>
    
    <a-layout :has-sider="true">
      <a-resize-box
        :directions="['right']"
        :width="sidebarWidthImmediate"
        @moving="handleSidebarResize"
        @moving-end="handleSidebarResizeEnd"
      >
        <div class="sidebar">侧边栏内容</div>
      </a-resize-box>
      
      <a-layout-content>
        <MainContent
          :sidebar-width="sidebarWidth"
          :width="contentWidth"
        />
      </a-layout-content>
    </a-layout>
  </a-layout>
</template>

<script setup lang="ts">
import { ref, computed } from 'vue'

const minSidebarWidth = 200
const sidebarWidthImmediate = ref(minSidebarWidth) // 视觉反馈变量
const sidebarWidth = ref(minSidebarWidth) // 数据传递变量
const resizerWidth = 6
const containerWidth = ref(1200)

const contentWidth = computed(() => {
  return containerWidth.value - sidebarWidth.value - resizerWidth
})

function handleSidebarResize(size: { width: number; height: number }) {
  sidebarWidthImmediate.value = Math.max(minSidebarWidth, size.width)
}

function handleSidebarResizeEnd() {
  sidebarWidth.value = sidebarWidthImmediate.value
}
</script>

注意事项

  1. 必须设置 has-sider="true":否则布局会混乱
  2. 宽度计算需减去拖拽条宽度:通常为 6px
  3. 设置最小宽度限制:防止侧边栏过小
  4. 使用双变量模式:避免拖拽时频繁触发子组件更新
相关推荐
开开心心就好4 小时前
批量提取PDF中的图片,直接导出原图
前端·javascript·支持向量机·智能手机·pdf·html·启发式算法
Setsuna_F_Seiei6 小时前
前端转型 Agent 开发 05 之 Agent Hooks 与 Checkpointer(让 Agent 从全自动转变人为可掌控)
前端·agent·ai编程
百万蹄蹄向前冲8 小时前
风扇转了一晚上MVP专家团翻车事故
前端·人工智能
默_笙8 小时前
🏛 给 AI 配一间办公室:Harness Engineering 六大模块与它的实现
前端·javascript
linux_cfan9 小时前
videojs v10 源代码系列解读:14 · 谓词守卫:在运行时安全地调用能力
前端·javascript·音视频
kyriewen10 小时前
我扒了 10,221 条 JD:腾讯技术岗 75% 在要 AI
前端·人工智能·ai编程
郑州光合科技余经理10 小时前
同城外卖小程序开发:下单成功后,后台导出能不能对上用户端状态
开发语言·前端·git·后端·uni-app·php·ai编程
+VX:Fegn089511 小时前
计算机毕业设计|基于springboot + vue旅游管理系统(源码+数据库+文档)
java·开发语言·vue.js·spring boot·课程设计
雪芽蓝域zzs11 小时前
第 7 章:双 Y 轴组合图(柱状 + 折线,看板高频场景)
vue.js·echars
IT_陈寒11 小时前
Vue的响应式让我熬到凌晨三点,原来漏了这个小细节
前端·人工智能·后端