pageContext

pageContextvite-plugin-ssr 的核心:它包含当前正在渲染的页面的所有信息。

请注意,在渲染新页面时,pageContext 将被丢弃然后重新创建。 这就是它被称为 pageContext(而非 appContext)的原因

它有内置属性,我们可以使用自定义属性对其扩展

内置

  • pageContext.Page: 页面 .page.js 文件的 export { Page }export default

  • pageContext.routeParams: 路由参数(例如 带路由字符串 /movie/@movieId 的页面的 pageContext.routeParams.movieId

  • pageContext.urlOriginal: 当前 URL

    在服务端,pageContext.urlOriginal 是我们在服务器中间件传入的值:

    // Server middleware
    app.get("*", async (req, res, next) => {
      const pageContextInit = {};
      // `pageContext.urlOriginal` is defined here
      pageContextInit.urlOriginal = req.url;
      const result = await renderPage(pageContextInit);
      /* ... */
    });

    在客户端,当使用 服务端路由 时,pageContext.urlOriginal 值是 undefined(除非我们使用 passToClient

    在客户端,当使用 客户端路由 时,pageContext.urlOriginal 的值是浏览器的当前 URL(window.location.href

  • pageContext.urlPathname: pageContext.urlParsed.pathname 的别名

  • pageContext.urlParsed: URL 详情:

    {
      origin: null | string;
      pathname: string;
      pathnameOriginal: string;
      search: Record<string, string>;
      searchAll: Record<string, string[]>;
      searchOriginal: null | string;
      hash: string;
      hashOriginal: null | string;
    }

    例如:

    // https://example.com/some-base-url/hello/s%C3%A9bastien?fruit=%C3%A2pple&fruit=orânge#%C3%A2ge
    {
      origin: 'https://example.com',
      pathname: '/hello/sébastien', // Without Base URL
      pathnameOriginal: '/some-base-url/hello/s%C3%A9bastien',
      search: { fruit: 'orânge' },
      searchAll: { fruit: ['âpple', 'orânge'] },
      searchOriginal: '?fruit=%C3%A2pple&fruit=orânge',
      hash: 'âge',
      hashOriginal: '#%C3%A2ge'
    }
  • pageContext.exports: 请参考 指南 > 自定义 Exports/Hooks.

  • pageContext.exportsAll: 跟 pageContext.exports 但包含所有导出

  • pageContext.isHydration: 当前页面是否已经渲染为 HTML,(对于用户导航到第一个页面通常为 true,如果用户在使用客户端路由时导航到新页面则为 false

  • pageContext.isBackwardNavigation: 用户是否正在返回历史记录。当用户点击浏览器的后退导航按钮或调用 history.back() 时,该值为 trueisBackwardNavigation 属性仅适用于客户端路由。 (使用服务端路由时,该值始终为 null

  • pageContext.is404: 发生了错误,不论错误是 404 Page Not Found 还是 500 Internal Server Error。请参考 API > _error.page.js

自定义

除了 vite-plugin-ssr 内置的 pageContext 值之外,我们还可以在以下位置自定义 pageContext 值:

  • Hooks onBeforeRender()render().
    export function onBeforeRender() {
      return {
        pageContext: {
          // 我们可以在这里自定义一些 `pageContext`
        },
      };
    }
    export function render() {
      return {
        documentHtml: escapeInject`<html><!--...--></html>`,
        pageContext: {
          // 我们可以在这里自定义一些 `pageContext`
        },
      };
    }
  • 服务器中间件
    // Server middleware
    app.get("*", async (req, res, next) => {
      const pageContextInit = {
        urlOriginal: req.url,
        // 我们可以在这里自定义一些 `pageContext`
      };
      const pageContext = await renderPage(pageContextInit);
      /* ... */
    });

浏览器

虽然一些 pageContext 值在客户端也可用,但大多数值仅在 Node.js 中可用,我们必须使用 passToClient 使它们在浏览器中可用

当使用 服务端路由 时,默认情况下浏览器中还提供以下内容:

  • pageContext.Page
  • pageContext.exports

当使用 客户端路由 时,默认情况下浏览器中还提供以下内容:

  • pageContext.Page
  • pageContext.exports
  • pageContext.isHydration
  • pageContext.isBackwardNavigation
  • pageContext.routeParams
  • pageContext.urlOriginal
  • pageContext.urlPathname
  • pageContext.urlParsed

TypeScript

TypeScript 工具类型:

// 服务端 `pageContext` 内置值
import type { PageContextBuiltIn } from "vite-plugin-ssr";

// 使用服务端路由时,客户端 `pageContext` 内置值
import type { PageContextBuiltInClient } from "vite-plugin-ssr/client";

// 使用客户端路由时,客户端 `pageContext` 内置值
import type { PageContextBuiltInClient } from "vite-plugin-ssr/client/router";