快速开始
创建 Qwik 应用,认识路由、数据加载、状态与表单。
Qwik 应用由服务端渲染器、文件路由和一组按需加载的符号组成。你不需要先规划代码分割,Optimizer 会在构建时完成这件事。
这条路径用 Qwik Router 创建一个完整应用。想先理解设计思想,可以先读心智模型。
01创建项目#
bun create qwik@latest
# 或使用其他包管理器
npm create qwik@latest
pnpm create qwik@latest
yarn create qwik@latestCLI 会询问项目名与模板。选择 playground 会得到包含 Qwik Router、示例路由和开发脚本的完整项目。
02启动开发服务器#
cd my-app
bun install
bun run dev开发服务器默认运行在 http://localhost:5173。命令与包管理器无关,用你习惯的工具即可。
03创建第一个路由#
src/routes 下的目录就是 URL。新建 src/routes/hello/index.tsx,默认导出一个组件:
import { component$ } from '@qwik.dev/core';
export default component$(() => {
return <h1>你好,Qwik</h1>;
});访问 /hello/ 就能看到页面。路由文件、layout.tsx 和 root.tsx 必须使用默认导出;其他组件可以用命名导出。
04从服务端加载数据#
routeLoader$ 在服务端执行,把结果序列化进 HTML。组件里调用返回的 hook,读取 .value:
import { component$ } from '@qwik.dev/core';
import { routeLoader$ } from '@qwik.dev/router';
export const useGreeting = routeLoader$(async () => {
return { message: '这份数据来自服务端' };
});
export default component$(() => {
const greeting = useGreeting();
return <p>{greeting.value.message}</p>;
});loader 的函数体不会发送到浏览器。页面首次渲染时,数据已经随 HTML 到达。
05让页面响应交互#
用 useSignal 保存状态,用 onClick$ 注册事件。事件处理代码是一个独立的 QRL,只在第一次交互时下载:
import { component$, useSignal } from '@qwik.dev/core';
export default component$(() => {
const count = useSignal(0);
return (
<button onClick$={() => count.value++}>
点击了 {count.value} 次
</button>
);
});这个数字由 signal 驱动。点击任意按钮,只有这块 DOM 更新。
06提交表单#
routeAction$ 处理服务端变更,<Form> 使用原生表单语义。开启 JavaScript 时走 SPA 提交,关闭 JavaScript 时浏览器照常 POST:
import { component$ } from '@qwik.dev/core';
import { Form, routeAction$ } from '@qwik.dev/router';
export const useSubscribe = routeAction$(async (data) => {
await db.subscribers.add(data.email);
return { success: true };
});
export default component$(() => {
const subscribe = useSubscribe();
return (
<Form action={subscribe}>
<input type="email" name="email" required />
<button type="submit">订阅</button>
{subscribe.value?.success && <p>已订阅</p>}
</Form>
);
});07添加组件样式#
Qwik 支持普通的 CSS 导入。需要把样式限定在组件内时,用 ?inline 导入并交给 useStylesScoped$:
import { component$, useStylesScoped$ } from '@qwik.dev/core';
import styles from './card.css?inline';
export default component$(() => {
useStylesScoped$(styles);
return <article class="card">一张卡片</article>;
});08验证生产构建#
开发服务器按文件提供模块,不能代表生产网络表现。运行预览命令,观察构建后的符号拆分与预加载:
bun run preview