From 2c6b978d8cd69258db887f92bc1bbe3d99b721c7 Mon Sep 17 00:00:00 2001 From: cfq Date: Fri, 30 Jan 2026 17:43:13 +0800 Subject: [PATCH] =?UTF-8?q?feat(LivePreviewEditor):=20=E4=B8=BA=E7=9B=AE?= =?UTF-8?q?=E5=BD=95=E4=BE=A7=E8=BE=B9=E6=A0=8F=E6=B7=BB=E5=8A=A0=E5=AE=BD?= =?UTF-8?q?=E5=BA=A6=E6=8B=96=E6=8B=BD=E8=B0=83=E6=95=B4=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 添加目录侧边栏的宽度拖拽调整支持,提升用户自定义布局的灵活性。 - 新增拖拽手柄组件,用户可调整侧边栏宽度(150px-600px范围) - 拖拽时提供视觉反馈(光标变化、手柄高亮) - 移除侧边栏固定宽度样式,改为JS动态控制 - 拖拽期间禁用过渡动画以避免视觉延迟 --- src/components/LivePreviewEditor.vue | 70 ++++++++++++++++++++++++++-- 1 file changed, 65 insertions(+), 5 deletions(-) diff --git a/src/components/LivePreviewEditor.vue b/src/components/LivePreviewEditor.vue index 4645f89..e37c87a 100644 --- a/src/components/LivePreviewEditor.vue +++ b/src/components/LivePreviewEditor.vue @@ -4,8 +4,12 @@
-
-
+
+
暂无大纲
+ + +
{ + isResizing.value = true; + startX = e.clientX; + startWidth = tocWidth.value; + + document.addEventListener('mousemove', handleResize); + document.addEventListener('mouseup', stopResize); + document.body.style.cursor = 'col-resize'; + document.body.style.userSelect = 'none'; +}; + +const handleResize = (e) => { + if (!isResizing.value) return; + const diff = e.clientX - startX; + const newWidth = Math.max(150, Math.min(600, startWidth + diff)); + tocWidth.value = newWidth; +}; + +const stopResize = () => { + isResizing.value = false; + document.removeEventListener('mousemove', handleResize); + document.removeEventListener('mouseup', stopResize); + document.body.style.cursor = ''; + document.body.style.userSelect = ''; +}; const debounce = (fn, delay) => { let timer = null; @@ -480,16 +521,20 @@ onUnmounted(() => { } .toc-sidebar { - width: 220px; + /* width: 220px; 由 JS 控制 */ flex-shrink: 0; border-right: 1px solid var(--border-color); overflow-y: auto; overflow-x: hidden; background-color: var(--card-background); - transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); + transition: width 0.3s cubic-bezier(0.4, 0, 0.2, 1), opacity 0.3s; opacity: 1; } +.toc-sidebar.resizing { + transition: none; +} + .toc-sidebar.collapsed { width: 0; opacity: 0; @@ -497,10 +542,25 @@ onUnmounted(() => { } .toc-content { - width: 220px; /* 固定宽度,防止内容挤压 */ + /* width: 220px; 由 JS 控制 */ padding: 12px 0; } +.toc-resizer { + width: 4px; + cursor: col-resize; + background-color: transparent; + transition: background-color 0.2s; + flex-shrink: 0; + margin-left: -1px; /* 重叠边框 */ + z-index: 10; + position: relative; +} + +.toc-resizer:hover, .toc-sidebar.resizing + .toc-resizer { + background-color: var(--primary-color); +} + .toc-empty { padding: 20px; text-align: center;