路由
PreffX 中的路由由根级的 url 信号驱动。导航会更新它,渲染的树会自动响应变化。该库与导航来源无关:在浏览器可用的 Navigation API 时会使用它,在 SSR 或无头环境中会回退到基于信号管理的独立导航。
读取 URL
url 工具函数是一个只读的 URL 信号:
tsx
import type { PC } from 'preffx';
export const Path: PC = (_props, { url }) => {
return <p>You are at: {url.value.pathname}</p>;
};触发导航
使用 navigate 跳转到另一个 URL:
tsx
import type { PC } from 'preffx';
export const Go: PC = (_props, { navigate }) => {
return <button onClick={() => navigate('/about')}>About</button>;
};使用 routes 的声明式路由
routes 工具函数接受一个「路径模式 → 组件」的映射,并返回一个响应式信号,其中保存着第一个匹配路由的渲染内容。匹配采用先到先得原则:模式按对象键的顺序进行检查。
tsx
import type { PC } from 'preffx';
export const App: PC = (_props, { routes }) => {
const content = routes({
'/': () => <div>Home</div>,
'/:lang?/user/:id': (_, { routeParams }) => (
<div>User #{routeParams.id} ({routeParams.lang || 'en'})</div>
),
'*': () => <div>Not found</div>
});
return (
<div>
<a href="/">Home</a>
<a href="/user/42">User page</a>
<a href="/ru/user/42">User page (ru)</a>
<a href="/unknown">Unknown page</a>
{content}
</div>
);
};路由模式
| 模式 | 描述 | 匹配示例 |
|---|---|---|
/users | 静态段 | /users |
/user/:id | 必填参数(:id) | /user/42 → { id: '42' } |
/:lang?/home | 可选参数(?);不存在时为空 | /home → { lang: '' } |
/files/* | 通配符 — 捕获其余部分(从末尾的 * 开始) | /files/a/b → { '*': 'a/b' } |
* | 全匹配 — 匹配任何路径 | /anything |
注意事项:
- 路由参数会自动进行 URI 解码。
- 一个模式匹配路径名的前缀:
/users也会匹配/users/42。当需要完全匹配时,请使用全匹配或更具体的模式。 *仅在作为最后一段时充当通配符;在其他位置会被视为字面量。- 匹配的路由参数可通过
routeParams获取。 - 在嵌套布局中,相对模式会相对于父路由匹配到的路径进行解析。
嵌套路由
在父组件中调用 routes();匹配到的子组件会被渲染进返回的信号中。匹配模式中的路由参数通过 routeParams 暴露,也可通过上下文(context)供后代使用。
工具函数汇总
| 选项 | 类型 | 描述 |
|---|---|---|
defaultURL | string | URL | 初始 URL(SSR 时传入请求 URL) |
url | ReadonlySignal<URL> | 当前 URL,响应式 |
navigate | (url, options?) | 导航到某个 URL |
routes | (paths) => signal | 首匹配路由渲染 |
routeParams | Record<string, string> | 当前匹配路由的参数 |