文件路由
用目录与 index 文件描述 URL,页面、端点与布局各司其职。
Qwik Router 是文件系统路由:src/routes 下的目录与文件直接决定 URL 结构。你不需要维护一张路由表,新增页面就是新增文件。
src/
└── routes/
├── layout.tsx # 根布局
├── index.tsx # /
├── about/
│ └── index.tsx # /about
├── blog/
│ ├── layout.tsx # /blog/* 的布局
│ ├── index.tsx # /blog
│ └── [slug]/
│ └── index.tsx # /blog/hello-world
├── api/
│ └── stats/
│ └── index.ts # JSON 端点
└── [...missing]/
└── index.tsx # 兜底页面01三种文件,三种职责#
| 文件 | 职责 | 返回 |
|---|---|---|
| index.tsx | 页面组件 | 渲染后的 HTML |
| index.ts | HTTP 端点 | JSON、文本或其他响应 |
| layout.tsx | 共享 UI 与中间件 | 包含 <Slot /> 的页面 |
import { component$ } from '@qwik.dev/core';
export default component$(() => {
return <h1>关于我们</h1>;
});index.ts 不导出组件,而是导出 onGet、onPost 等请求处理函数。它适合 REST 接口、Webhook 与文件下载。
import type { RequestHandler } from '@qwik.dev/router';
export const onGet: RequestHandler = ({ json }) => {
json(200, { online: true });
};02动态路由#
方括号目录表示动态段。[slug] 匹配一个路径段,[...all] 匹配剩余所有段,参数从 useLocation() 的 params 读取。
import { component$ } from '@qwik.dev/core';
import { useLocation } from '@qwik.dev/router';
export default component$(() => {
const loc = useLocation();
return <h1>文章:{loc.params.slug}</h1>;
});| 文件 | 匹配的 URL | params |
|---|---|---|
| routes/user/[username]/index.tsx | /user/foo | { username: 'foo' } |
| routes/post/[...all]/index.tsx | /post/2026/11/qwik | { all: '2026/11/qwik' } |
| routes/shop/[category]/[id]/index.tsx | /shop/book/42 | { category: 'book', id: '42' } |
03路由优先级#
多条路由同时匹配时,Qwik Router 从左到右逐段比较:静态段优先于 [param],[param] 优先于 [...catchAll]。目录顺序与括号分组不影响结果。
/pricing → pricing/index.tsx
/news/feed.xml → [section]/feed.xml/index.ts
/news/today → [section]/[topic]/index.tsx
/acme/settings/billing → [org]/[...path]/index.tsx04布局#
layout.tsx 同时承担两件事:包裹子路由的 UI,以及在渲染前执行的中间件。子页面通过 <Slot /> 插入布局内容。
import { component$, Slot } from '@qwik.dev/core';
export default component$(() => {
return (
<div class="shell">
<header>Qwik 中文站点</header>
<main>
<Slot />
</main>
</div>
);
});布局可以嵌套,请求也会逐层经过每一级的 onRequest。例如 /admin/users 会依次执行根布局、admin/layout.tsx、页面自身的处理函数。
05SPA 导航#
<Link> 渲染一个真正的 <a> 标签:没有 JavaScript 时是普通页面跳转,有 JavaScript 时升级为 SPA 导航。优先使用它,而不是在按钮里手写跳转。
import { component$ } from '@qwik.dev/core';
import { Link, useNavigate } from '@qwik.dev/router';
export default component$(() => {
const nav = useNavigate();
return (
<nav>
<Link href="/docs/">文档</Link>
<button onClick$={() => nav('/about')}>关于</button>
</nav>
);
});| 写法 | 行为 |
|---|---|
| <Link href="/docs/"> | 可访问的页面跳转,支持预取 |
| <Link reload> | 重新执行当前路由的 loader 并刷新 |
| useNavigate()('/path') | 在代码中触发导航 |
| useNavigate()() | 刷新当前页面 |
<Link> 默认在链接进入视口时预取路由代码,在用户表现出点击意图时预取数据。滚动位置由浏览器 history 恢复,刷新、前进后退都不会闪动。