PageSourceSearch

https://devcodex-labs.github.io/vextjs/static/js/async/route-a27c32180ed6.36ee4e260e.js

js devcodex-labs.github.io collected 2026-10-03 09:00:38 UTC 37,706 bytes, 1 lines download raw bytes

1"use strict";(self.rspackChunkvext_website=self.rspackChunkvext_website||[]).push([[6212],{3652(s,n,e){e.r(n);var r=e(4848),o=e(8453);function i(s){let n={a:"a",code:"code",h1:"h1",h2:"h2",p:"p",pre:"pre",span:"span",...(0,o.R)(),...s.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsxs)(n.h1,{id:"数据流",children:[(0,r.jsx)(n.a,{className:"rp-header-anchor","aria-hidden":"true",href:"#数据流",children:"#"}),"数据流"]}),"\n",(0,r.jsxs)(n.p,{children:["Vext 前端数据从服务端开始。Route handler 调用 services,准备 JSON-safe 数据,再传给 ",(0,r.jsx)(n.code,{children:"res.render()"}),"。"]}),"\n",(0,r.jsxs)(n.h2,{id:"首屏数据",children:[(0,r.jsx)(n.a,{className:"rp-header-anchor","aria-hidden":"true",href:"#首屏数据",children:"#"}),"首屏数据"]}),"\n",(0,r.jsx)(r.Fragment,{children:(0,r.jsx)(n.pre,{className:"shiki css-variables",style:{backgroundColor:"var(--shiki-background)",color:"var(--shiki-foreground)"},tabIndex:"0",lang:"ts",children:(0,r.jsxs)(n.code,{children:[(0,r.jsxs)(n.span,{className:"line",children:[(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-keyword)"},children:"export"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-keyword)"},children:" default"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:" (app) "}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-keyword)"},children:"=>"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:" {"})]}),"\n",(0,r.jsxs)(n.span,{className:"line",children:[(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-constant)"},children:"  app"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-function)"},children:".get"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:"("})]}),"\n",(0,r.jsxs)(n.span,{className:"line",children:[(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-string-expression)"},children:'    "/dashboard"'}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-punctuation)"},children:","})]}),"\n",(0,r.jsxs)(n.span,{className:"line",children:[(0,r.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:"    { auth"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-keyword)"},children:":"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-constant)"},children:" true"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-punctuation)"},children:","}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:" cache"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-keyword)"},children:":"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:" { ttl"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-keyword)"},children:":"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-constant)"},children:" 30_000"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:" } }"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-punctuation)"},children:","})]}),"\n",(0,r.jsxs)(n.span,{className:"line",children:[(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-keyword)"},children:"    async"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:" (req"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-punctuation)"},children:","}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:" res) "}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-keyword)"},children:"=>"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:" {"})]}),"\n",(0,r.jsxs)(n.span,{className:"line",children:[(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-keyword)"},children:"      const"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:" { "}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-constant)"},children:"userId"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:" } "}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-keyword)"},children:"="}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-constant)"},children:" req"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:".auth;"})]}),"\n",(0,r.jsxs)(n.span,{className:"line",children:[(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-keyword)"},children:"      if"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:" ("}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-keyword)"},children:"!"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:"userId) {"})]}),"\n",(0,r.jsxs)(n.span,{className:"line",children:[(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-constant)"},children:"        req"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-function)"},children:"."}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-constant)"},children:"app"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-function)"},children:".throw"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:"("}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-constant)"},children:"401"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-punctuation)"},children:","}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-string-expression)"},children:' "控制台需要已认证的用户 ID"'}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:");"})]}),"\n",(0,r.jsx)(n.span,{className:"line",children:(0,r.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:"      }"})}),"\n",(0,r.jsx)(n.span,{className:"line"}),"\n",(0,r.jsxs)(n.span,{className:"line",children:[(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-keyword)"},children:"      const"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-constant)"},children:" summary"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-keyword)"},children:" ="}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-keyword)"},children:" await"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-constant)"},children:" app"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-function)"},children:"."}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-constant)"},children:"services"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-function)"},children:"."}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-constant)"},children:"dashboard"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-function)"},children:".summary"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:"(userId);"})]}),"\n",(0,r.jsxs)(n.span,{className:"line",children:[(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-constant)"},children:"      res"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-function)"},children:".render"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:"("}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-string-expression)"},children:'"dashboard"'}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-punctuation)"},children:","}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:" {"})]}),"\n",(0,r.jsxs)(n.span,{className:"line",children:[(0,r.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:"        summary"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-punctuation)"},children:","})]}),"\n",(0,r.jsx)(n.span,{className:"line",children:(0,r.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:"      });"})}),"\n",(0,r.jsxs)(n.span,{className:"line",children:[(0,r.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:"    }"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-punctuation)"},children:","})]}),"\n",(0,r.jsx)(n.span,{className:"line",children:(0,r.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:"  );"})}),"\n",(0,r.jsx)(n.span,{className:"line",children:(0,r.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:"};"})})]})})}),"\n",(0,r.jsxs)(n.p,{children:["应用注册 ",(0,r.jsx)(n.code,{children:"auth()"})," 后,",(0,r.jsx)(n.code,{children:"auth: true"})," 负责保护路由,",(0,r.jsx)(n.code,{children:"req.auth"})," 承载框架提供的身份与 claims。用户资料属于业务数据:应由自己的 service 加载,不能假设 Vext 会注入 ",(0,r.jsx)(n.code,{children:"req.user"}),"。"]}),"\n",(0,r.jsx)(n.p,{children:"页面在 SSR 和 hydration 中接收同一份对象:"}),"\n",(0,r.jsx)(r.Fragment,{children:(0,r.jsx)(n.pre,{className:"shiki css-variables",style:{backgroundColor:"var(--shiki-background)",color:"var(--shiki-foreground)"},tabIndex:"0",lang:"tsx",children:(0,r.jsxs)(n.code,{children:[(0,r.jsxs)(n.span,{className:"line",children:[(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-keyword)"},children:"export"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-keyword)"},children:" default"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-keyword)"},children:" function"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-function)"},children:" DashboardPage"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:"(props"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-keyword)"},children:":"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:" { summary"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-keyword)"},children:":"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-function)"},children:" DashboardSummary"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:" }) {"})]}),"\n",(0,r.jsxs)(n.span,{className:"line",children:[(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-keyword)"},children:"  return"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:" <"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-constant)"},children:"Dashboard"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-function)"},children:" summary"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-keyword)"},children:"="}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:"{"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-constant)"},children:"props"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:".summary} />;"})]}),"\n",(0,r.jsx)(n.span,{className:"line",children:(0,r.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:"}"})})]})})}),"\n",(0,r.jsxs)(n.h2,{id:"layout-data",children:[(0,r.jsx)(n.a,{className:"rp-header-anchor","aria-hidden":"true",href:"#layout-data",children:"#"}),"Layout Data"]}),"\n",(0,r.jsxs)(n.p,{children:["导航、用户菜单、工作区信息、后台权限等 shell 级数据放在 ",(0,r.jsx)(n.code,{children:"options.layoutData"}),"。下面的 handler 片段假定所在路由已经声明 ",(0,r.jsx)(n.code,{children:"auth: true"}),":"]}),"\n",(0,r.jsx)(r.Fragment,{children:(0,r.jsx)(n.pre,{className:"shiki css-variables",style:{backgroundColor:"var(--shiki-background)",color:"var(--shiki-foreground)"},tabIndex:"0",lang:"ts",children:(0,r.jsxs)(n.code,{children:[(0,r.jsxs)(n.span,{className:"line",children:[(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-keyword)"},children:"const"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:" { "}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-constant)"},children:"userId"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:" } "}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-keyword)"},children:"="}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-constant)"},children:" req"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:".auth;"})]}),"\n",(0,r.jsxs)(n.span,{className:"line",children:[(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-keyword)"},children:"if"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:" ("}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-keyword)"},children:"!"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:"userId) {"})]}),"\n",(0,r.jsxs)(n.span,{className:"line",children:[(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-constant)"},children:"  req"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-function)"},children:"."}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-constant)"},children:"app"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-function)"},children:".throw"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:"("}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-constant)"},children:"401"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-punctuation)"},children:","}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-string-expression)"},children:' "控制台需要已认证的用户 ID"'}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:");"})]}),"\n",(0,r.jsx)(n.span,{className:"line",children:(0,r.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:"}"})}),"\n",(0,r.jsx)(n.span,{className:"line"}),"\n",(0,r.jsxs)(n.span,{className:"line",children:[(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-keyword)"},children:"const"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-constant)"},children:" user"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-keyword)"},children:" ="}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-keyword)"},children:" await"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-constant)"},children:" app"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-function)"},children:"."}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-constant)"},children:"services"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-function)"},children:"."}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-constant)"},children:"user"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-function)"},children:".findById"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:"(userId);"})]}),"\n",(0,r.jsx)(n.span,{className:"line"}),"\n",(0,r.jsxs)(n.span,{className:"line",children:[(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-constant)"},children:"res"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-function)"},children:".render"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:"("})]}),"\n",(0,r.jsxs)(n.span,{className:"line",children:[(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-string-expression)"}
1,children:'  "admin/dashboard"'}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-punctuation)"},children:","})]}),"\n",(0,r.jsxs)(n.span,{className:"line",children:[(0,r.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:"  { metrics }"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-punctuation)"},children:","})]}),"\n",(0,r.jsx)(n.span,{className:"line",children:(0,r.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:"  {"})}),"\n",(0,r.jsxs)(n.span,{className:"line",children:[(0,r.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:"    layoutData"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-keyword)"},children:":"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:" {"})]}),"\n",(0,r.jsxs)(n.span,{className:"line",children:[(0,r.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:"      user"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-punctuation)"},children:","})]}),"\n",(0,r.jsxs)(n.span,{className:"line",children:[(0,r.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:"      nav"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-keyword)"},children:":"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-keyword)"},children:" await"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-constant)"},children:" app"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-function)"},children:"."}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-constant)"},children:"services"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-function)"},children:"."}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-constant)"},children:"nav"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-function)"},children:".admin"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:"(userId)"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-punctuation)"},children:","})]}),"\n",(0,r.jsxs)(n.span,{className:"line",children:[(0,r.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:"    }"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-punctuation)"},children:","})]}),"\n",(0,r.jsxs)(n.span,{className:"line",children:[(0,r.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:"  }"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-punctuation)"},children:","})]}),"\n",(0,r.jsx)(n.span,{className:"line",children:(0,r.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:");"})})]})})}),"\n",(0,r.jsx)(n.p,{children:"Layout 不直接 import services,而是消费 route handler 传入的数据。"}),"\n",(0,r.jsxs)(n.h2,{id:"多语言-messages",children:[(0,r.jsx)(n.a,{className:"rp-header-anchor","aria-hidden":"true",href:"#多语言-messages",children:"#"}),"多语言 Messages"]}),"\n",(0,r.jsxs)(n.p,{children:["页面文案来自 ",(0,r.jsx)(n.code,{children:"src/frontend/locales/**"})," 和可选 render messages:"]}),"\n",(0,r.jsx)(r.Fragment,{children:(0,r.jsx)(n.pre,{className:"shiki css-variables",style:{backgroundColor:"var(--shiki-background)",color:"var(--shiki-foreground)"},tabIndex:"0",lang:"ts",children:(0,r.jsxs)(n.code,{children:[(0,r.jsxs)(n.span,{className:"line",children:[(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-constant)"},children:"res"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-function)"},children:".render"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:"("}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-string-expression)"},children:'"settings"'}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-punctuation)"},children:","}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:" props"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-punctuation)"},children:","}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:" {"})]}),"\n",(0,r.jsxs)(n.span,{className:"line",children:[(0,r.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:"  locale"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-keyword)"},children:":"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-constant)"},children:" req"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:".locale"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-punctuation)"},children:","})]}),"\n",(0,r.jsxs)(n.span,{className:"line",children:[(0,r.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:"  messages"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-keyword)"},children:":"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:" {"})]}),"\n",(0,r.jsxs)(n.span,{className:"line",children:[(0,r.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:"    settings"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-keyword)"},children:":"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:" { title"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-keyword)"},children:":"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-string-expression)"},children:' "Settings"'}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:" }"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-punctuation)"},children:","})]}),"\n",(0,r.jsxs)(n.span,{className:"line",children:[(0,r.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:"  }"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-punctuation)"},children:","})]}),"\n",(0,r.jsx)(n.span,{className:"line",children:(0,r.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:"});"})})]})})}),"\n",(0,r.jsx)(n.p,{children:"客户端读取 typed object:"}),"\n",(0,r.jsx)(r.Fragment,{children:(0,r.jsx)(n.pre,{className:"shiki css-variables",style:{backgroundColor:"var(--shiki-background)",color:"var(--shiki-foreground)"},tabIndex:"0",lang:"tsx",children:(0,r.jsxs)(n.code,{children:[(0,r.jsxs)(n.span,{className:"line",children:[(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-keyword)"},children:"const"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-constant)"},children:" i18n"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-keyword)"},children:" ="}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-function)"},children:" useVextI18n"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:"(locale);"})]}),"\n",(0,r.jsxs)(n.span,{className:"line",children:[(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-keyword)"},children:"return"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:" <"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-string-expression)"},children:"h1"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:">{"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-constant)"},children:"i18n"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:"."}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-constant)"},children:"settings"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:".title}</"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-string-expression)"},children:"h1"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:">;"})]})]})})}),"\n",(0,r.jsxs)(n.h2,{id:"同路由导航",children:[(0,r.jsx)(n.a,{className:"rp-header-anchor","aria-hidden":"true",href:"#同路由导航",children:"#"}),"同路由导航"]}),"\n",(0,r.jsx)(n.p,{children:"Hydration 后,Vext 可以把同一个 document route 协商为版本化 page result。这里没有第二套 loader/action 注册 API:原 route handler 及其中间件、auth/session、CSRF、validation、cache、timeout、redirect 和 error 行为仍是唯一事实源。"}),"\n",(0,r.jsxs)(n.p,{children:["稳定公开面是 ",(0,r.jsx)(n.code,{children:"Link"}),"、",(0,r.jsx)(n.code,{children:"Form"}),"、",(0,r.jsx)(n.code,{children:"navigate"}),"、",(0,r.jsx)(n.code,{children:"prefetch"}),"、",(0,r.jsx)(n.code,{children:"revalidate"}),"、",(0,r.jsx)(n.code,{children:"useNavigation"}),"、",(0,r.jsx)(n.code,{children:"useFetcher"})," 与 ",(0,r.jsx)(n.code,{children:"useRouteData"}),"。"]}),"\n",(0,r.jsx)(r.Fragment,{children:(0,r.jsx)(n.pre,{className:"shiki css-variables",style:{backgroundColor:"var(--shiki-background)",color:"var(--shiki-foreground)"},tabIndex:"0",lang:"tsx",children:(0,r.jsxs)(n.code,{children:[(0,r.jsxs)(n.span,{className:"line",children:[(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-keyword)"},children:"import"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:" {"})]}),"\n",(0,r.jsxs)(n.span,{className:"line",children:[(0,r.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:"  Form"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-punctuation)"},children:","})]}),"\n",(0,r.jsxs)(n.span,{className:"line",children:[(0,r.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:"  Link"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-punctuation)"},children:","})]}),"\n",(0,r.jsxs)(n.span,{className:"line",children:[(0,r.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:"  revalidate"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-punctuation)"},children:","})]}),"\n",(0,r.jsxs)(n.span,{className:"line",children:[(0,r.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:"  useFetcher"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-punctuation)"},children:","})]}),"\n",(0,r.jsxs)(n.span,{className:"line",children:[(0,r.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:"  useNavigation"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-punctuation)"},children:","})]}),"\n",(0,r.jsxs)(n.span,{className:"line",children:[(0,r.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:"  useRouteData"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-punctuation)"},children:","})]}),"\n",(0,r.jsxs)(n.span,{className:"line",children:[(0,r.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:"} "}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-keyword)"},children:"from"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-string-expression)"},children:' "vextjs/frontend"'}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:";"})]}),"\n",(0,r.jsx)(n.span,{className:"line"}),"\n",(0,r.jsxs)(n.span,{className:"line",children:[(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-keyword)"},children:"export"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-keyword)"},children:" default"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-keyword)"},children:" function"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-function)"},children:" DashboardPage"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-foreground)"}
1,children:"() {"})]}),"\n",(0,r.jsxs)(n.span,{className:"line",children:[(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-keyword)"},children:"  const"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-constant)"},children:" data"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-keyword)"},children:" ="}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-function)"},children:" useRouteData"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:"<{ summary"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-keyword)"},children:":"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-function)"},children:" DashboardSummary"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:" }>();"})]}),"\n",(0,r.jsxs)(n.span,{className:"line",children:[(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-keyword)"},children:"  const"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-constant)"},children:" navigation"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-keyword)"},children:" ="}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-function)"},children:" useNavigation"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:"();"})]}),"\n",(0,r.jsxs)(n.span,{className:"line",children:[(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-keyword)"},children:"  const"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-constant)"},children:" details"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-keyword)"},children:" ="}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-function)"},children:" useFetcher"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:"<{ summary"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-keyword)"},children:":"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-function)"},children:" DashboardSummary"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:" }>();"})]}),"\n",(0,r.jsx)(n.span,{className:"line"}),"\n",(0,r.jsxs)(n.span,{className:"line",children:[(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-keyword)"},children:"  return"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:" ("})]}),"\n",(0,r.jsxs)(n.span,{className:"line",children:[(0,r.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:"    <"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-string-expression)"},children:"main"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:">"})]}),"\n",(0,r.jsxs)(n.span,{className:"line",children:[(0,r.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:"      <"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-string-expression)"},children:"h1"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:">控制台</"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-string-expression)"},children:"h1"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:">"})]}),"\n",(0,r.jsxs)(n.span,{className:"line",children:[(0,r.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:"      <"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-string-expression)"},children:"p"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-function)"},children:" data-state"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-keyword)"},children:"="}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:"{"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-constant)"},children:"navigation"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:".phase}>{"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-constant)"},children:"data"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:"?."}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-constant)"},children:"summary"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:".label}</"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-string-expression)"},children:"p"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:">"})]}),"\n",(0,r.jsxs)(n.span,{className:"line",children:[(0,r.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:"      <"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-constant)"},children:"Link"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-function)"},children:" href"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-keyword)"},children:"="}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-string-expression)"},children:'"/reports"'}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-function)"},children:" prefetch"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-keyword)"},children:"="}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-string-expression)"},children:'"click"'}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:">"})]}),"\n",(0,r.jsx)(n.span,{className:"line",children:(0,r.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:"        报表"})}),"\n",(0,r.jsxs)(n.span,{className:"line",children:[(0,r.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:"      </"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-constant)"},children:"Link"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:">"})]}),"\n",(0,r.jsxs)(n.span,{className:"line",children:[(0,r.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:"      <"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-constant)"},children:"Form"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-function)"},children:" action"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-keyword)"},children:"="}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-string-expression)"},children:'"/reports"'}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-function)"},children:" method"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-keyword)"},children:"="}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-string-expression)"},children:'"post"'}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:">"})]}),"\n",(0,r.jsxs)(n.span,{className:"line",children:[(0,r.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:"        <"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-string-expression)"},children:"button"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-function)"},children:" type"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-keyword)"},children:"="}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-string-expression)"},children:'"submit"'}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:">创建报表</"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-string-expression)"},children:"button"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:">"})]}),"\n",(0,r.jsxs)(n.span,{className:"line",children:[(0,r.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:"      </"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-constant)"},children:"Form"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:">"})]}),"\n",(0,r.jsxs)(n.span,{className:"line",children:[(0,r.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:"      <"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-string-expression)"},children:"button"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-function)"},children:" onClick"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-keyword)"},children:"="}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:"{() "}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-keyword)"},children:"=>"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-constant)"},children:" details"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-function)"},children:".load"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:"("}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-string-expression)"},children:'"/reports?view=compact"'}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:")}>"})]}),"\n",(0,r.jsx)(n.span,{className:"line",children:(0,r.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:"        加载摘要"})}),"\n",(0,r.jsxs)(n.span,{className:"line",children:[(0,r.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:"      </"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-string-expression)"},children:"button"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:">"})]}),"\n",(0,r.jsxs)(n.span,{className:"line",children:[(0,r.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:"      <"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-string-expression)"},children:"button"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-function)"},children:" onClick"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-keyword)"},children:"="}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:"{() "}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-keyword)"},children:"=>"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-function)"},children:" revalidate"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-foreground)"}
1,children:"()}>刷新</"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-string-expression)"},children:"button"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:">"})]}),"\n",(0,r.jsxs)(n.span,{className:"line",children:[(0,r.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:"    </"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-token-string-expression)"},children:"main"}),(0,r.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:">"})]}),"\n",(0,r.jsx)(n.span,{className:"line",children:(0,r.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:"  );"})}),"\n",(0,r.jsx)(n.span,{className:"line",children:(0,r.jsx)(n.span,{style:{color:"var(--shiki-foreground)"},children:"}"})})]})})}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.code,{children:"Link"})," 支持 ",(0,r.jsx)(n.code,{children:'prefetch="none" | "click" | "visible"'}),",默认是 ",(0,r.jsx)(n.code,{children:'"click"'}),"。",(0,r.jsx)(n.code,{children:"Form"})," 保留普通字符串 ",(0,r.jsx)(n.code,{children:"action"})," 与 HTTP method,因此禁用 JavaScript 后仍会正常提交 document 请求。",(0,r.jsx)(n.code,{children:"useFetcher()"})," 复用相同 route,但不改变浏览器 history。"]}),"\n",(0,r.jsxs)(n.h2,{id:"导航生命周期",children:[(0,r.jsx)(n.a,{className:"rp-header-anchor","aria-hidden":"true",href:"#导航生命周期",children:"#"}),"导航生命周期"]}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.code,{children:"useNavigation()"})," 返回 ",(0,r.jsx)(n.code,{children:"idle"}),"、",(0,r.jsx)(n.code,{children:"loading"}),"、",(0,r.jsx)(n.code,{children:"submitting"}),"、",(0,r.jsx)(n.code,{children:"revalidating"}),"、",(0,r.jsx)(n.code,{children:"error"})," 或 ",(0,r.jsx)(n.code,{children:"aborted"}),"。Revalidation 在新结果提交前保留 last-known-good 页面;新导航会取消旧请求,等价 GET 会去重,",(0,r.jsx)(n.code,{children:"revalidate({ routeId, path, tags, keys })"})," 可在当前 locale 与 auth/session 分区内失效匹配条目。"]}),"\n",(0,r.jsxs)(n.p,{children:["浏览器只在增强导航时请求 ",(0,r.jsx)(n.code,{children:"application/vnd.vext.page+json;v=1"}),"。协议、build id、权限、解码或 route asset 不兼容时会执行且仅执行一次 document navigation。Page envelope 是内部 runtime 协议,不是用户需要实现的 RPC 格式。"]}),"\n",(0,r.jsxs)(n.h2,{id:"客户端-api-调用与缓存边界",children:[(0,r.jsx)(n.a,{className:"rp-header-anchor","aria-hidden":"true",href:"#客户端-api-调用与缓存边界",children:"#"}),"客户端 API 调用与缓存边界"]}),"\n",(0,r.jsxs)(n.p,{children:["不是页面导航的 JSON API 调用继续使用生成的 typed API client 或普通 ",(0,r.jsx)(n.code,{children:"fetch"}),"。首屏与页面导航数据通常应由 ",(0,r.jsx)(n.code,{children:"res.render()"})," 提供。Vext 浏览器缓存按 route、规范化 URL、locale、auth/session identity、protocol 与 contract digest 分区;认证结果或 ",(0,r.jsx)(n.code,{children:"no-store"})," page result 不会写入共享 public cache。"]})]})}function l(){let s=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},{wrapper:n}={...(0,o.R)(),...s.components};return n?(0,r.jsx)(n,{...s,children:(0,r.jsx)(i,{...s})}):i(s)}l.__RSPRESS_PAGE_META={},l.__RSPRESS_PAGE_META["zh%2Ffrontend%2Fdata-flow.md"]={toc:[{id:"首屏数据",text:"首屏数据",depth:2},{id:"layout-data",text:"Layout Data",depth:2},{id:"多语言-messages",text:"多语言 Messages",depth:2},{id:"同路由导航",text:"同路由导航",depth:2},{id:"导航生命周期",text:"导航生命周期",depth:2},{id:"客户端-api-调用与缓存边界",text:"客户端 API 调用与缓存边界",depth:2}],title:"数据流",headingTitle:"数据流",frontmatter:{}},e.d(n,{default:()=>l})}}]);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.