From 6e12b3376943131b64c81ee8fc0405dd1762eff6 Mon Sep 17 00:00:00 2001 From: xfy Date: Thu, 9 Jul 2026 14:29:34 +0800 Subject: [PATCH] =?UTF-8?q?fix(write):=20=E5=BD=BB=E5=BA=95=E4=BF=AE?= =?UTF-8?q?=E5=A4=8D=E9=AA=A8=E6=9E=B6=E5=B1=8F=E9=AB=98=E5=BA=A6=E4=B8=8D?= =?UTF-8?q?=E6=92=91=E6=BB=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 骨架屏在两条渲染路径都被高度链断裂卡住,内容只占页面 40-50%, 底部大片空白。 根因:高度链在两处父容器断裂,导致骨架屏无法引用到确定高度: 1. 未登录态(admin_layout):骨架屏被包在 div.p-10.animate-pulse, 该 div 是普通块级元素,无 flex-1 不撑满 main、非 flex 容器使 骨架屏 flex-1 无效、无 h-full。SSR 初始态走这条。 2. 登录态(write.rs 覆盖层):absolute inset-0 虽撑满,但非 flex 容器,骨架屏 flex-1 无意义;改 h-full 又遇 height:100% 在 非显式高度父容器下解析不可靠的经典坑。 修复:统一让两条路径的父容器都成为 flex flex-col,骨架屏根用 flex-1(比 height:100% 可靠,不依赖父显式 height): - admin_layout 包裹层: p-10.animate-pulse → flex-1.min-h-0. flex.flex-col.animate-pulse(去掉对 write 不合适的 p-10, 非 write 页面 padding 由 main_class 自带) - write.rs 覆盖层: absolute inset-0 → absolute inset-0 flex flex-col - write_skeleton 根: h-full → flex-1 --- src/components/admin_layout.rs | 4 +++- src/components/write_skeleton.rs | 6 +++--- src/pages/admin/write.rs | 2 +- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/components/admin_layout.rs b/src/components/admin_layout.rs index de70e97..dc53662 100644 --- a/src/components/admin_layout.rs +++ b/src/components/admin_layout.rs @@ -146,7 +146,9 @@ pub fn AdminLayout() -> Element { div { class: "flex-1 flex flex-col min-w-0 h-screen p-2 md:p-4", div { class: "flex-1 bg-[var(--color-paper-theme)] rounded-[2rem] shadow-sm border border-[var(--color-paper-border)] overflow-hidden relative flex flex-col", main { class: "{main_class}", - div { class: "p-10 animate-pulse", + // flex-1 撑满 main(使 write 骨架屏能引用到确定高度), + // 非 write 页面的 py-12 padding 由 main_class 自带,这里不重复加。 + div { class: "flex-1 min-h-0 flex flex-col animate-pulse", { match route { Route::Write {} => rsx! { WriteSkeleton {} }, diff --git a/src/components/write_skeleton.rs b/src/components/write_skeleton.rs index 2f90ca6..9322fa8 100644 --- a/src/components/write_skeleton.rs +++ b/src/components/write_skeleton.rs @@ -13,9 +13,9 @@ use dioxus::prelude::*; #[component] pub fn WriteSkeleton() -> Element { rsx! { - // 根:WriteSkeleton 放在 write.rs 的 absolute inset-0 覆盖层里, - // 故用 h-full 撑满该层(父层非 flex,flex-1 无效),内部再 flex flex-col 分配高度。 - div { class: "relative h-full flex flex-col min-h-0 overflow-hidden", + // 根:父层是 flex 容器(write.rs 覆盖层 / admin_layout 包裹层均为 flex flex-col), + // 用 flex-1 撑满父层高度(比 height:100% 更可靠,不依赖父显式 height)。 + div { class: "relative flex-1 flex flex-col min-h-0 overflow-hidden", // 两栏容器:与真实页面一致,左 flex-1 + 右 w-80 div { class: "flex-1 min-h-0 flex", // 左栏(主写作区) diff --git a/src/pages/admin/write.rs b/src/pages/admin/write.rs index 5cf1f01..8349d1b 100644 --- a/src/pages/admin/write.rs +++ b/src/pages/admin/write.rs @@ -414,7 +414,7 @@ fn write_editor(post_id: Option) -> Element { // 底栏作为 main 直接子元素永远贴卡片底沿,不随内容滚动,也无需 sticky。 div { class: "relative flex flex-col w-full min-h-0 flex-1", if loading() { - div { class: "absolute inset-0 z-10 bg-paper-theme", WriteSkeleton {} } + div { class: "absolute inset-0 z-10 bg-paper-theme flex flex-col", WriteSkeleton {} } } // 两栏容器:flex-1 分配空间,自身不滚动(min-h-0),滚动职责下放给左右两栏。