Skip to main content

Module ssr_resource

Module ssr_resource 

Source
Expand description

页面 SSR 数据资源(route_data:值类型擦除为 JSON 文本,取数函数随分包加载)。 SSR 数据资源。

§路由数据:route_data

懒加载路由的 LazyRoute::data() 编译进主包(SSR 会多次执行 view(),资源只能在 data() 里建)。若在那里直接建 Resource<Result<T, ApiError>>,每个路由的数据 类型、反序列化代码与 server fn 客户端都会进主包,所有页面首屏一起付费。

route_data 把资源的值类型擦除成 JSON 文本(RawJson,所有路由共用同一份 Resource 实例化),取数函数由调用方写成 #[leptos::lazy] 函数、返回 PageJson<T>: 服务端直接调用并编码,客户端首次取数时才加载它所在的分包。view() 里 data.await 得到 Result<T, ApiError>,解码代码随视图分包加载。SSR 的视图直接 克隆服务端的取数结果,JSON 文本只用于水合;正文这类 SSR 已渲染进 HTML 的大字段可用 PageJson::with_hydration 在水合数据里换成占位。

ⓘ
#[leptos::lazy]
async fn fetch_post(slug: String) -> PageJson<PublicPostResponse> {
    PageJson::new(get_public_post_by_slug(slug).await)
}
// data():  post: route_data(move || slug.get(), fetch_post),
// view():  match post.await { Ok(..) => .., Err(..) => .. }

§悬停预取:prefetch_route_data

悬停、聚焦、触屏按下站内链接时,route_prefetch 调用各路由的 prefetch_data 提前请求 页面数据,结果存进浏览器端的小缓存;之后导航到该页,route_data 的取数闭包先查缓存, 命中就直接复用进行中或已完成的请求。

  • 键 = 取数函数的类型(TypeId::of::<F>())+ source 的值。具名函数项与 unit() 返回的闭包类型都是唯一的,data() 与预取两边传同一个函数就是同一个键;闭包字面量 每处类型都不同,永远不会命中,只是不预取,不会取错数据。
  • 一次性:命中即取走。完成后保留 10 秒,过期丢弃;进行中的请求不按 TTL 过期。
  • 出错不缓存:错误结果只交给已经在等的消费者,之后的导航重新请求。
  • 只用于不依赖会话的公开数据;服务端不保留任何跨请求状态(非 wasm 为空操作)。

§主包内的数据

主包组件自己的数据(页脚)同样走 route_data。 JsonSliceCodec 给 share_meta 的 SharedValue 用:水合解码与 server fn 共用 serde_json::from_slice 的实例化(默认 JsonSerdeCodec 用 from_str,同一类型会多出一份 StrRead 反序列化代码)。

Structs§

ErasedKey 🔒
JsonSliceCodec
Resource 的 JSON 编解码器:编码 serde_json::to_string,解码 serde_json::from_slice。
PageJson
路由取数函数(#[leptos::lazy])的返回值:已编码的 Result<T, ApiError>。
RawJson
路由数据资源的统一值类型:Result<T, ApiError> 的 JSON 文本,也就是写进水合数据的内容。 SSR 时还带着取数结果本身,视图直接克隆它,不再把刚编码的文本解析回来。
RawJsonCodec
RawJson 的文本原样作为资源的序列化形式,不再二次编码。
RouteData
路由数据句柄:在 data() 里由 route_data 创建,view() 里 .await 得到结果。
RouteDataRegistry 🔒
SSR:本次请求已创建的路由数据资源,键为(取数函数类型, source 值)。

Traits§

DynKey 🔒
路由数据键:擦除 source 的具体类型,所有路由共用一份 Resource 实例化。

Functions§

encode_page_json 🔒
erased_route_resource 🔒
唯一一处 Resource<RawJson, _> 实例化:source、fetch 都是 trait 对象。
prefetch_route_data
悬停预取一份路由数据:键与 route_data 相同(fetcher 的类型 + source)。 之后导航到该页时 route_data 直接复用结果。只用于不依赖会话的公开数据。
provide_route_data_registry
在应用根部调用:SSR 时为本次请求建立路由数据登记表(见 route_data)。浏览器端不做任何事。
resolve_page_json 🔒
SSR 直接克隆取数结果;水合与客户端取数解析 JSON 文本。
route_data
创建路由数据(语义同 Resource::new:服务端执行 fetcher 并把结果写进 HTML, 客户端水合直接复用;source 变化即重新请求)。fetcher 应是 #[leptos::lazy] 函数,主包里只留下这一份与数据类型无关的资源代码。
unit
把无参取数函数包成 Fn(()),与 route_data(|| (), unit(f)) 搭配。 返回的闭包类型只取决于 f 的函数项类型,data() 与悬停预取得到同一个预取键。

Type Aliases§

ErasedFetch 🔒
ErasedSource 🔒
RawFuture 🔒
RegistryEntry 🔒
登记表条目:(取数函数类型, source 值, 资源)。