文档中心
探索 DWeb 框架的无限可能,构建下一代高性能 Web 应用
路由系统 (Router)
DWeb 使用文件系统路由,路由文件位于 `routes` 目录。文件路径自动映射为 URL 路径,无需手动配置路由表。
文件系统路由
路由文件位于 routes 目录。文件路径自动映射为 URL 路径:
路由规则
index.tsx- 映射到目录的根路径[id].tsx- 动态路由参数[...slug].tsx- 捕获所有路由[[slug]].tsx- 可选参数路由
动态路由
使用方括号 [id] 创建动态路由参数:
访问 /users/123 时,params.id 将是 '123'。
捕获所有路由
使用 [...slug] 捕获所有剩余路径段:
访问 /docs/getting-started/installation 时,params.slug 将是 ['getting-started', 'installation']。
可选参数路由
使用双括号 [[slug]] 创建可选参数路由:
/posts 和 /posts/hello-world 都会匹配此路由。
使用 load 函数获取数据
load 函数在服务端执行,用于在页面渲染前获取数据。返回的数据会自动传递给页面组件的 data 属性。
**优势:**
在服务端执行,减少客户端请求
支持 SSR,提高 SEO 和首屏性能
可以访问数据库、文件系统等服务器资源
数据在服务端获取,更安全
⚠️ 重要限制:页面组件不能是异步函数
**页面组件不能定义为 async function**。如果需要进行异步操作(如数据获取),请使用以下方式:
**❌ 错误示例:**
// ❌ 错误:页面组件不能是异步函数 export default async function UserPage({ params }: PageProps) { const user = await fetchUser(params.id); // 这会导致错误 return
**✅ 正确示例:使用 useEffect**
// ✅ 正确:使用 useEffect 处理异步操作 import { useEffect, useState } from 'preact/hooks'; import type { PageProps } from '@dreamer/dweb'; export default function UserPage({ params }: PageProps) { const [user, setUser] = useState<{ name: string } | null>(null); const [loading, setLoading] = useState(true); useEffect(() => { const fetchUser = async () => { try { const response = await fetch(`/api/users/${params.id}`); const data = await response.json(); setUser(data); } catch (error) { console.error('获取用户失败:', error); } finally { setLoading(false); } }; fetchUser(); }, [params.id]); if (loading) { return
**✅ 推荐:使用 load 函数(见上方示例)**
使用 `load` 函数在服务端获取数据是最佳实践,可以充分利用 SSR 的优势,提高性能和 SEO。
路由优先级
路由匹配按以下优先级(从高到低):
- 精确匹配(如
/users/index.tsx) - 动态路由(如
/users/[id].tsx) - 捕获所有路由(如
/users/[...slug].tsx) - 可选参数路由(如
/users/[[slug]].tsx)
**注意:**当多个路由都能匹配同一个路径时,框架会选择优先级最高的路由。
路由约定文件
DWeb 框架支持以下约定文件,它们有特殊的作用:
_app.tsx- 根应用组件,提供 HTML 文档结构(DOCTYPE、head、body 等),示例:routes/_app.tsx_layout.tsx- 布局组件,提供页面布局结构,示例:routes/_layout.tsx_middleware.ts- 中间件文件,在请求处理前执行,示例:routes/_middleware.ts_404.tsx- 404 错误页面,当路由不匹配时显示,示例:routes/_404.tsx_error.tsx- 错误页面,当发生错误时显示,示例:routes/_error.tsx
更多关于约定文件的说明,请参考 路由约定文档。