From d41012a0abedcb39cc81193f04733a8aa294e055 Mon Sep 17 00:00:00 2001 From: Jz0ojiang Date: Tue, 11 Aug 2026 16:51:49 +0800 Subject: [PATCH] =?UTF-8?q?=E8=87=AA=E5=8A=A8=E6=BB=9A=E5=8A=A8=E6=94=B9?= =?UTF-8?q?=E4=B8=BA=E6=8A=98=E5=8F=A0=E8=BF=9B=E5=9C=BA=E6=97=B6=E9=A2=84?= =?UTF-8?q?=E9=87=8F=E6=9C=80=E7=BB=88=E9=AB=98=E5=BA=A6=EF=BC=9B=E4=BE=A7?= =?UTF-8?q?=E6=A0=8F=E5=AF=BC=E8=88=AA=E6=8C=89=E9=92=AE=E9=97=B4=E8=B7=9D?= =?UTF-8?q?=E5=8A=A0=E5=A4=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 原来在 nextTick 量高度,此时折叠动画刚从 0 起步,配置展开量到 0 不滚, 链式代理量到半截滚一半。enter 钩子触发时元素刚插入、还是自然高度, 在把高度压到 0 之前先量,得到的就是折叠结束后的位置,滚动和折叠同时 开跑。触发点也从开关挪进 foldEnter,两个包装函数随之删掉。 --- web/App.vue | 2 +- web/views/InboundDetail.vue | 26 ++++++++++---------------- 2 files changed, 11 insertions(+), 17 deletions(-) diff --git a/web/App.vue b/web/App.vue index ff867c4..b0da466 100644 --- a/web/App.vue +++ b/web/App.vue @@ -239,7 +239,7 @@ const current = computed(() => NAV.find((n) => n.key === active.value)) padding: 0; display: flex; flex-direction: column; - gap: 2px; + gap: var(--s-1); flex: 1; } diff --git a/web/views/InboundDetail.vue b/web/views/InboundDetail.vue index 2fd42a1..fefd377 100644 --- a/web/views/InboundDetail.vue +++ b/web/views/InboundDetail.vue @@ -132,22 +132,19 @@ const open = ref(false) const rootEl = ref(null) /** - * 展开配置或拨开链式代理后,详情底部可能长到窗口外,把新出现的内容滚进视野。 - * 只挂在这两个动作上:tab 切换也会变高度,但来回切 tab 时页面跟着跳只会晕。 + * 详情底部长出窗口外时,把新内容滚进视野。必须在 foldEnter 把高度压到 0 之前调: + * 那一刻元素刚插入、还是自然高度,量到的 bottom 就是折叠结束后的最终位置, + * 滚动因此能和折叠同时开跑、停在正确的地方;动画中途量到的只有半截。 + * 只由配置展开和链式代理拨开触发(见 foldEnter):tab 切换也变高度,但不滚, + * 来回切 tab 时页面跟着跳只会晕。 */ -async function revealBottom() { - await nextTick() +function revealBottom() { const el = rootEl.value if (!el) return const gap = el.getBoundingClientRect().bottom + 16 - window.innerHeight if (gap > 0) window.scrollBy({ top: gap, behavior: 'smooth' }) } -function toggleOpen() { - open.value = !open.value - if (open.value) void revealBottom() -} - /** * 切换选中的入站时,内容淡出淡入,容器高度从旧值滑到新值。 * 高度过渡没法纯 CSS 做:auto 不可插值。所以离开前把当前高度钉住, @@ -166,6 +163,8 @@ function lockHeight() { */ function foldEnter(element: Element, done: () => void) { const el = element as HTMLElement + // 先量再压:此刻元素是自然高度,revealBottom 量到的就是折叠结束后的位置 + revealBottom() el.style.height = '0' el.style.overflow = 'hidden' void el.offsetHeight @@ -253,11 +252,6 @@ const chainOn = computed({ }, }) -function toggleChain() { - chainOn.value = !chainOn.value - if (chainOn.value) void revealBottom() -} - // ── 草稿预览 ──────────────────────────────────────────── // 上半部分的显示规则只有一条:草稿和已保存一致时显示现实;不一致时显示「按草稿保存后 // 的样子」。点击的语义看卡片本身:现在就存在的成员任何时候点了都立刻生效,只有保存后 @@ -590,7 +584,7 @@ const complete = computed(
- @@ -627,7 +621,7 @@ const complete = computed( role="switch" :aria-checked="chainOn" :class="['switch', chainOn && 'is-on']" - @click="toggleChain" + @click="chainOn = !chainOn" >