deno.com
本页内容

使用 Deno 构建 Qwik

Qwik 是一个 JavaScript 框架,它通过利用可恢复性而不是水合作用来提供即时加载的 Web 应用程序。在本教程中,我们将构建一个简单的 Qwik 应用程序并使用 Deno 运行它。该应用程序将显示恐龙列表。当您单击其中一个时,它会将您带到包含更多详细信息的恐龙页面。

我们将介绍如何使用 Deno 构建一个简单的 Qwik 应用

随时直接跳到源代码或按照下面的步骤操作!

搭建 Qwik 应用 跳转到标题

我们可以使用 deno 像这样创建一个新的 Qwik 项目

deno init --npm qwik@latest

这将引导您完成 Qwik 和 Qwik City 的设置过程。在这里,我们选择了最简单的“Empty App”部署和 npm 依赖项。

完成后,您将拥有如下所示的项目结构

.
├── node_modules/
├── public/
└── src/
    ├── components/
    │   └── router-head/
    │       └── router-head.tsx
    └── routes/
        ├── index.tsx
        ├── layout.tsx
        ├── service-worker.ts
        ├── entry.dev.tsx
        ├── entry.preview.tsx
        ├── entry.ssr.tsx
        ├── global.css
        └── root.tsx
├── .eslintignore
├── .eslintrc.cjs
├── .gitignore
├── .prettierignore
├── package-lock.json
├── package.json
├── qwik.env.d.ts
├── README.md
├── tsconfig.json
└── vite.config.ts

其中大部分是我们不会触及的样板配置。以下是一些重要的文件,用于了解 Qwik 的工作原理

  • src/components/router-head/router-head.tsx:管理 Qwik 应用程序中不同路由的 HTML head 元素(如标题、元标记等)。
  • src/routes/index.tsx:应用程序的主入口点和主页,用户访问根 URL 时看到的内容。
  • src/routes/layout.tsx:定义环绕页面的通用布局结构,允许您维护一致的 UI 元素,如页眉和页脚。
  • src/routes/service-worker.ts:处理应用程序的渐进式 Web 应用 (PWA) 功能、离线缓存和后台任务。
  • src/routes/entry.ssr.tsx:控制应用程序的服务器端渲染方式,管理初始 HTML 生成和水合过程。
  • src/routes/root.tsx:作为应用程序外壳的根组件,包含全局提供程序和主路由结构。

现在我们可以在应用程序中构建我们自己的路由和文件。

设置数据和类型定义 跳转到标题

我们将首先将我们的恐龙数据添加到新的 ./src/data 目录中,命名为 dinosaurs.json

// ./src/data/dinosaurs.json

{
  "dinosaurs": [
    {
      "name": "Tyrannosaurus Rex",
      "description": "A massive carnivorous dinosaur with powerful jaws and tiny arms."
    },
    {
      "name": "Brachiosaurus",
      "description": "A huge herbivorous dinosaur with a very long neck."
    },
    {
      "name": "Velociraptor",
      "description": "A small but fierce predator that hunted in packs."
    }
    // ...
  ]
}

这是我们将从中提取数据的地方。在完整的应用程序中,这些数据将来自数据库。

⚠️️ 在本教程中,我们硬编码了数据。但是您可以连接到各种数据库,甚至可以将 ORM(如 Prisma)与 Deno 一起使用

接下来,让我们为我们的恐龙数据添加类型定义。我们将它放在 ./src/ 中的 types.ts

// ./src/types.ts

export type Dino = {
  name: string;
  description: string;
};

接下来,让我们添加 API 路由来服务这些数据。

添加 API 路由 跳转到标题

首先,让我们创建路由来加载索引页面的所有恐龙。此 API 端点使用 Qwik City 的 RequestHandler 来创建一个 GET 端点,该端点加载并返回我们的恐龙数据,并使用 json 助手进行正确的响应格式化。我们将下面的内容添加到 ./src/routes/api/dinosaurs/index.ts 中的新文件中

// ./src/routes/api/dinosaurs/index.ts

import { RequestHandler } from "@builder.io/qwik-city";
import data from "~/data/dinosaurs.json" with { type: "json" };

export const onGet: RequestHandler = async ({ json }) => {
  const dinosaurs = data;
  json(200, dinosaurs);
};

接下来,让我们创建 API 路由来获取单个恐龙的信息。这从 URL 中获取参数,并使用它在我们的恐龙数据中搜索。我们将以下代码添加到 ./src/routes/api/dinosaurs/[name]/index.ts

// ./src/routes/api/dinosaurs/[name]/index.ts

import { RequestHandler } from "@builder.io/qwik-city";
import data from "~/data/dinosaurs.json" with { type: "json" };

export const onGet: RequestHandler = async ({ params, json }) => {
  const { name } = params;
  const dinosaurs = data;

  if (!name) {
    json(400, { error: "No dinosaur name provided." });
    return;
  }

  const dinosaur = dinosaurs.find(
    (dino) => dino.name.toLowerCase() === name.toLowerCase(),
  );

  if (!dinosaur) {
    json(404, { error: "No dinosaur found." });
    return;
  }

  json(200, dinosaur);
};

现在 API 路由已连接并提供数据,让我们创建两个前端页面:索引页面和单独的恐龙详细信息页面。

构建前端 跳转到标题

我们将通过使用 Qwik 的 routeLoader$ 进行服务器端数据获取来更新我们的 ./src/routes/index.tsx 文件,从而创建我们的主页。此 component$ 在 SSR 期间通过 useDinosaurs() 加载和渲染恐龙数据

// ./src/routes/index.tsx

import { component$ } from "@builder.io/qwik";
import { Link, routeLoader$ } from "@builder.io/qwik-city";
import type { Dino } from "~/types";
import data from "~/data/dinosaurs.json" with { type: "json" };

export const useDinosaurs = routeLoader$(() => {
  return data;
});

export default component$(() => {
  const dinosaursSignal = useDinosaurs();

  return (
    <div class="container mx-auto p-4">
      <h1 class="text-3xl font-bold mb-4">Welcome to the Dinosaur app</h1>
      <p class="mb-4">Click on a dinosaur below to learn more.</p>
      <ul class="space-y-2">
        {dinosaursSignal.value.dinosaurs.map((dinosaur: Dino) => (
          <li key={dinosaur.name}>
            <Link
              href={`/${dinosaur.name.toLowerCase()}`}
              class="text-blue-600 hover:underline"
            >
              {dinosaur.name}
            </Link>
          </li>
        ))}
      </ul>
    </div>
  );
});

现在我们有了主索引页面,让我们为单个恐龙信息添加一个页面。我们将使用 Qwik 的 动态路由,其中 [name] 作为每只恐龙的键。此页面利用 routeLoader$ 根据 URL 参数获取单个恐龙详细信息,并在找不到恐龙时内置错误处理。

该组件使用与我们的索引页面相同的 SSR 模式,但具有基于参数的数据加载和更简单的单个恐龙详细信息显示布局

// ./src/routes/[name]/index.tsx

import { component$ } from "@builder.io/qwik";
import { Link, routeLoader$ } from "@builder.io/qwik-city";
import type { Dino } from "~/types";
import data from "~/data/dinosaurs.json" with { type: "json" };

export const useDinosaurDetails = routeLoader$(({ params }): Dino => {
  const { dinosaurs } = data;
  const dinosaur = dinosaurs.find(
    (dino: Dino) => dino.name.toLowerCase() === params.name.toLowerCase(),
  );

  if (!dinosaur) {
    throw new Error("Dinosaur not found");
  }

  return dinosaur;
});

export default component$(() => {
  const dinosaurSignal = useDinosaurDetails();

  return (
    <div class="container mx-auto p-4">
      <h1 class="text-3xl font-bold mb-4">{dinosaurSignal.value.name}</h1>
      <p class="mb-4">{dinosaurSignal.value.description}</p>
      <Link href="/" class="text-blue-600 hover:underline">
        Back to all dinosaurs
      </Link>
    </div>
  );
});

现在我们已经构建了我们的路由和前端组件,我们可以运行我们的应用程序

deno task dev

这将启动位于 localhost:5173 的应用程序

完成!

后续步骤 跳转到标题

🦕 现在您可以使用 Deno 构建和运行 Qwik 应用程序了!以下是一些您可以增强恐龙应用程序的方法

Qwik 应用程序的后续步骤可能是使用 Qwik 的延迟加载功能来加载恐龙图像和其他组件,或者为复杂功能添加客户端状态管理。

您找到所需内容了吗?

隐私政策