From 0ddefd0d5d297a9dc24a1717f321e3fdb2cb4142 Mon Sep 17 00:00:00 2001 From: Jz0ojiang Date: Tue, 11 Aug 2026 16:42:43 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BE=A7=E6=A0=8F=E6=94=B6=E6=8B=A2=E6=97=B6?= =?UTF-8?q?=E5=AF=BC=E8=88=AA=E6=8C=89=E9=92=AE=E8=B7=9F=E7=9D=80=E7=BC=A9?= =?UTF-8?q?=E7=AA=84=EF=BC=9B=E9=85=8D=E7=BD=AE=E5=8C=BA=E9=AB=98=E5=BA=A6?= =?UTF-8?q?=E6=8A=98=E5=8F=A0=E5=8A=A8=E7=94=BB=EF=BC=9B=E4=BE=A7=E6=A0=8F?= =?UTF-8?q?=E4=B8=8D=E5=86=8D=E7=89=B5=E5=8A=A8=E9=A1=B5=E9=9D=A2=E5=86=85?= =?UTF-8?q?=E5=AE=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 导航按钮宽度写死 159px 而不是 100%,百分比到像素之间没法插值,收拢时 按钮平滑缩成 36px 的方形贴住图标,高亮块不再被裁切出血。配置表单和 链式代理段的出现消失改成高度折叠(量出目标高度做插值,margin 换成 padding 否则那一截在动画之外瞬跳)。路由页「新增」按钮的文字不再跟着 侧栏密度隐藏:侧栏收拢是侧栏自己的事。 --- web/App.vue | 15 ++++++++++++- web/views/InboundDetail.vue | 42 +++++++++++++++++++++++++++++++++++-- web/views/RouterPage.vue | 4 ++-- 3 files changed, 56 insertions(+), 5 deletions(-) diff --git a/web/App.vue b/web/App.vue index 1c1e490..ff867c4 100644 --- a/web/App.vue +++ b/web/App.vue @@ -244,7 +244,8 @@ const current = computed(() => NAV.find((n) => n.key === active.value)) } .nav-item { - width: 100%; + /* 写死而不是 100%:百分比到像素之间没法插值,宽度动画会直接跳变 */ + width: 159px; display: flex; align-items: center; gap: var(--s-3); @@ -256,6 +257,18 @@ const current = computed(() => NAV.find((n) => n.key === active.value)) cursor: pointer; text-align: left; white-space: nowrap; + overflow: hidden; + /* width 跟侧栏同节奏,颜色沿用全局的 0.15s;transition 不叠加,这里要写全 */ + transition: + width 0.3s ease, + color 0.15s ease, + background-color 0.15s ease, + border-color 0.15s ease; +} + +/* 收拢后按钮缩成正方形贴着图标,高亮块不再被裁切:8 + 18 + 8 加两侧边框 = 36 */ +.is-compact .nav-item { + width: 36px; } .nav-item:hover { diff --git a/web/views/InboundDetail.vue b/web/views/InboundDetail.vue index c43a0b8..2fd42a1 100644 --- a/web/views/InboundDetail.vue +++ b/web/views/InboundDetail.vue @@ -160,6 +160,39 @@ function lockHeight() { el.style.overflow = 'hidden' } +/** + * v-if 内容的展开收起动画:高度在 0 和实际值之间过渡,结束后清掉内联样式。 + * 给配置表单和链式代理段用。auto 高度不可插值,只能量出来做。 + */ +function foldEnter(element: Element, done: () => void) { + const el = element as HTMLElement + el.style.height = '0' + el.style.overflow = 'hidden' + void el.offsetHeight + el.style.transition = 'height 0.15s ease' + el.style.height = `${String(el.scrollHeight)}px` + el.addEventListener( + 'transitionend', + () => { + el.style.transition = '' + el.style.height = '' + el.style.overflow = '' + done() + }, + { once: true }, + ) +} + +function foldLeave(element: Element, done: () => void) { + const el = element as HTMLElement + el.style.height = `${String(el.offsetHeight)}px` + el.style.overflow = 'hidden' + void el.offsetHeight + el.style.transition = 'height 0.15s ease' + el.style.height = '0' + el.addEventListener('transitionend', done, { once: true }) +} + function settleHeight() { const el = rootEl.value if (!el || !el.style.height) return @@ -507,6 +540,7 @@ const complete = computed( +

链式代理 @@ -546,6 +580,7 @@ const complete = computed( />

+
@@ -560,6 +595,7 @@ const complete = computed( +

代理

@@ -631,6 +667,7 @@ const complete = computed(
+
@@ -899,12 +936,13 @@ h3 { transform: rotate(90deg); } -/* 表单不套盒子,靠小标题和一条分割线分段(设计基调第 2 条:不要卡片套卡片) */ +/* 表单不套盒子,靠小标题和一条分割线分段(设计基调第 2 条:不要卡片套卡片)。 + 上方留白用 padding 而不是 margin:margin 在高度折叠动画之外,会瞬跳 */ .form { display: flex; flex-direction: column; gap: var(--s-3); - margin-top: var(--s-4); + padding-top: var(--s-4); } .form h4 { diff --git a/web/views/RouterPage.vue b/web/views/RouterPage.vue index d63c436..8c7268f 100644 --- a/web/views/RouterPage.vue +++ b/web/views/RouterPage.vue @@ -28,7 +28,6 @@ import type { ListenerFields } from '../api' import type { GroupView } from '../runtime' import { optimisticSelect, providerLines, reloadRuntime, runtime } from '../runtime' import { useDelayTest } from '../delay-test' -import { density } from '../prefs' import ConfirmDialog from '../components/ConfirmDialog.vue' import InboundList from '../components/InboundList.vue' import InboundDetail from './InboundDetail.vue' @@ -258,9 +257,10 @@ async function removeConfirmed() { +