取数据

让我们实现https://example.com/product/abc123,以便我们可以获取产品的详细信息。

文件目录

第一步是构建目录和文件,以便我们可以创建 /product/abc123 路由。

──src/
  └─routes/
    └─product/
        └─[skuId]/
            └─index.tsx     # https://example.com/product/1234

实现 onGet

在“page”中,onGet 函数获取数据(通常来自数据库或其他存储)。 检索到的数据可以直接返回为 JSON (Accept: application/json) 或用作组件的输入以渲染 HTML (Accept: text/html)。 onGet 函数接收 params 以提取用于进行数据查找的参数。

在此示例中,onGet 函数通过 useEndpoint() 函数返回 在我们的组件内部使用的 产品数据。

// File: src/routes/product/[skuId]/details/index.tsx
import type { RequestHandler } from '@builder.io/qwik-city';

interface ProductData {
  skuId: string;
  price: number;
  description: string;
}

export const onGet: RequestHandler<ProductData> = async ({ params }) => {
  // put your DB access here, we are hard coding a response for simplicity.
  return {
    skuId: params.skuId,
    price: 123.45,
    description: `Description for ${params.skuId}`,
  };
};

在组件使用 onGet

onGet 函数获取数据并使用 useEndpoint() 将其提供给组件。

import { Resource, component$, useStore } from '@builder.io/qwik';
import type { RequestHandler } from '@builder.io/qwik-city';
import { useEndpoint } from "@builder.io/qwik-city";


interface ProductData { ... }
export const onGet: RequestHandler<ProductData> = async ({ params }) => { ... };

export default component$(() => {
  const productData = useEndpoint<ProductData>();
  return (
    <Resource
      value={productData}
      onPending={() => <div>Loading...</div>}
      onRejected={() => <div>Error</div>}
      onResolved={(product) => (
        <>
          <h1>Product: {product.skuId}</h1>
          <p>Price: {product.price}</p>
          <p>{product.description}</p>
        </>
      )}
    />
  );
});
  1. 请注意,数据请求处理程序和组件是在同一个文件中定义的。数据由 onGet 函数提供,组件由模块默认导出。
  2. 组件使用 useEndpoint() 函数来获取数据。useEndpoint() 函数直接在服务器上调用 onGet 函数,但在客户端使用 fetch()。 您的组件在使用数据时不需要考虑服务器客户端的差异。 useEndpoint() 函数返回一个ResourceReturn 类型的对象。 Resource 是类似 Promise 的对象,可以被 Qwik 序列化。
  3. onGet 函数在组件之前调用。这允许 onGet 返回 404 或重定向,以防数据不可用。
  4. 注意 <Resource> JSX 元素的使用。 Resource 的目的是允许客户端渲染 useEndpoint() 资源的不同状态。
  5. 在服务器上,<Resource> 元素将暂停渲染,直到 Resource resolved或rejected。这是因为我们不希望服务器渲染 loading...。 (服务器需要知道组件何时准备好序列化为 HTML。)
  6. 您可以使用 typeof onGet 来保持 onGet 函数和 useEndpoint() 类型同步。 TypeScript 足够聪明,可以为您确定类型。

上述所有操作都是为了从组件中抽象出数据访问,从而在服务器和客户端上都产生正确的行为。

Made with ❤️ by