尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Wasp 路由与页面指南:用 route/page 声明式构建 React 应用

Wasp 路由与页面指南:用 route/page 声明式构建 React 应用 Wasp 路由与页面指南用 route/page 声明式构建 React 应用【免费下载链接】waspThe batteries-included full-stack framework for the AI era. Develop JS/TS web apps (React, Node.js, and Prisma) using declarative code that abstracts away complex full-stack features like auth, background jobs, RPC, email sending, end-to-end type safety, single-command deployment, and more.项目地址: https://gitcode.com/GitHub_Trending/wa/waspWasp 的route与page声明是构建 Web 应用客户端的基础它们用两行声明式代码把 URL 路径和 React 组件绑定在一起从而免去手写 React Router 配置的繁琐工作。本文以 Wasp 0.14 官方教程「3. Pages Routes」为核心结合仓库中 TodoApp 示例examples/tutorials/TodoApp和生成器模板源码waspc/data/Generator/templates完整讲解声明语法、动态路由参数、TypeScript 类型安全链接以及清理脚手架项目的实战步骤。读完本文你将能独立在 Wasp 项目中定义任意页面、传递 URL 参数并理解其底层的路由生成机制。适用范围说明本教程针对 Wasp^0.14.0版本的经典 Wasp 语言.wasp文件写法这也是仓库中 web/versioned_docs/version-0.14/tutorial 教程系列所对应的版本。当前仓库的 examples/tutorials/TodoApp/main.wasp.ts 已迁移到基于 TypeScript 的新式规范wasp.sh/spec但其「路由绑定页面、路径含参数」的核心语义与本文一致可对照阅读。从零认识 route 与 page两行声明搞定页面用wasp new TodoApp创建项目后默认的 main.wasp 文件中已经带有一对route和page声明它们是 Wasp 客户端路由的最小骨架route RootRoute { path: /, to: MainPage } page MainPage { // 指定页面的 React 实现由 src/MainPage.{jsx,tsx} 导出 // 使用标准 JS import 语法。用 src 引用 src 文件夹内的文件。 component: import { MainPage } from src/MainPage }这两行声明合在一起告诉 Wasp当用户访问/时渲染从src/MainPage.{jsx,tsx}中导出的命名组件。注意src是 Wasp 提供的特殊路径别名指向项目的src目录写组件引用时务必以它开头而不能用相对路径。从 Wasp 的声明类型模型看一个完整的页面需要两个声明协作route描述页面可以从哪个 URL 路径被访问包含三个关键属性pathURL 路径支持 React Router 风格的动态参数如/hello/:nameto指向与该路由绑定的page声明通过 page 名称引用可选authRequired设置为true时该页面要求用户登录后才能访问未登录会跳转到登录页——这一点在 examples/tutorials/TodoApp/main.wasp.ts 中route(RootRoute, /, page(MainPage, { authRequired: true }))有实际体现。page定义一个 Web 页面及其渲染的 React 组件核心属性是component即从src目录导入的 React 组件。底层的路由生成机制Wasp 会读取main.wasp中的全部route声明为每个声明生成一条 React Router 路由。这一点可以从生成器模板源码中得到印证在 waspc/data/Generator/templates/sdk/wasp/client/app/router.tsx 中getRouteObjects函数遍历routes对象把每个route.to作为path、对应的页面组件放入路由表中再统一挂载到根路径/的children下const userDefinedRoutes Object.entries(routes).map(([routeKey, route]) { return { path: route.to, ...routesMapping[routeKey], } })也就是说你在 Wasp 里写的每条route声明最终都会被编译成 React Router 的路由对象——你不需要手写Switch、Route这些样板代码Wasp 的代码生成器替你完成了这部分工作。MainPage 组件一个普通的 React 函数组件page声明引用的MainPage本身没有任何特殊之处就是一个标准的 React 函数组件import waspLogo from ./waspLogo.png import ./Main.css export const MainPage () { // ... }TypeScript 版本仅把文件后缀换成.tsx组件签名不变import waspLogo from ./waspLogo.png import ./Main.css export const MainPage () { // ... }它引用了与组件同目录的 CSS 文件和 Logo 图片这些资源会被 Vite 正常打包处理。这里的关键在于Wasp 只关心组件的「导出方式」与「文件位置」是否符合component声明组件内部怎么写完全是标准 React 的自由发挥空间。相比手写 React Router 的项目Wasp 的优势在于「定义、构建、运行」全链路都由框架接管你只需保证组件被正确命名导出剩下的路由注册、页面挂载、开发服务器与构建流程全部自动完成。这也是 Wasp 文档原句 That is all the code you need! 的含义所在。添加第二个页面动态路由参数/hello/:name要增加页面只需再添加一组routepage声明。更关键的是path中可以使用与 React Router 完全一致的参数语法:前缀从而支持动态 URLroute HelloRoute { path: /hello/:name, to: HelloPage } page HelloPage { component: import { HelloPage } from src/HelloPage }当用户访问/hello/their-name时Wasp 会渲染src/HelloPage.{jsx,tsx}导出的组件并把 URL 参数以与 React Router 相同的方式注入组件 props。JavaScript 版组件通过props.match.params读取参数export const HelloPage (props) { return divHeres {props.match.params.name}!/div }TypeScript 版需要为RouteComponentProps声明泛型参数让路由参数获得完整的类型推断import { RouteComponentProps } from react-router-dom export const HelloPage ( props: RouteComponentProps{ name: string } ) { return divHeres {props.match.params.name}!/div }保存后访问http://localhost:3000/hello/johnny页面就会显示 Heres johnny!。整个过程中无需重启wasp startWasp 的开发服务器会热重载新的路由声明——这也是声明式框架对开发体验的直接提升。动态参数的类型安全Link 组件与 routes 对象对 TypeScript 用户Wasp 还提供了类型安全的链接方案避免手写字符串拼接 URL 导致的类型错误。在 web/versioned_docs/version-0.14/advanced/links.md 中有完整说明核心是wasp/client/router导出的两个 API。Link组件与react-router-dom的Link用法相似但to必须是main.wasp中真实存在的路由路径params中的键值必须与路径参数一一对应import { Link } from wasp/client/router export const TaskList () { // ... return ( div {tasks.map((task) ( Link key{task.id} to/task/:id // 必须传一个合法的 Wasp 路由路径 params{{ id: task.id }} // 路径中每个参数都必须正确传入 {task.description} /Link ))} /div ) }Link还支持search与hash属性例如to/task/:id params{{ id: task.id }} search{{ sortBy: date }} hashcomments最终会生成/task/1?sortBydate#comments这样的链接。其底层实现waspc/data/Generator/templates/sdk/wasp/client/router/Link.tsx通过interpolatePath把to、params、search、hash组合成最终 URL再转发给 React Router 的Link渲染。routes对象为应用中的每条路由生成一个带build方法的对象用编程方式构建链接import { routes } from wasp/client/router const linkToTask routes.TaskRoute.build({ params: { id: 1 } }) // 得到 /task/1routes对象的类型定义位于 waspc/data/Generator/templates/sdk/wasp/client/router/types.ts从中可以看到 Wasp 甚至通过ExpandRouteOnOptionalStaticSegments类型工具支持可选路径段如/users/tasks?/:id?并自动展开为多种路由组合——这说明 Wasp 的路由类型系统不仅覆盖普通参数还覆盖了可选段这类复杂场景。需要说明的是Link组件与routes对象的类型安全能力依赖 TypeScript 项目.tsx/.ts纯 JavaScript 项目也可以使用routes对象但无法获得参数层面的编译期校验。清理脚手架把项目恢复到最小可用状态看完路由与页面的工作机制后接下来要基于脚手架搭建真正的 Todo 应用第一步是清理。1. 精简 MainPage 组件把 src/MainPage.jsx或.tsx中脚手架自带的演示代码替换为最小内容export const MainPage () { return divHello world!/div }TypeScript 版本完全相同export const MainPage () { return divHello world!/div }此时启动wasp start访问http://localhost:3000首页应显示 Hello world!效果如上文开头的截图所示。2. 删除冗余文件随后删除不再需要的文件src/Main.css脚手架自带的全局样式Todo 教程后续不需要src/waspLogo.png脚手架 Logo 图片src/HelloPage.{jsx,tsx}教程其余部分用不到这个动态参数示例页。3. 同步移除 main.wasp 中的声明文件删掉之后main.wasp里对应的route和page声明必须一并删除否则 Wasp 在编译时会因为找不到src/HelloPage导出而报错——这是 Wasp 声明与源码文件必须保持一致的一个典型约束。清理后main.wasp应为app TodoApp { wasp: { version: ^0.14.0 }, title: TodoApp } route RootRoute { path: /, to: MainPage } page MainPage { component: import { MainPage } from src/MainPage }其中app声明web/versioned_docs/version-0.14/tutorial/02-project-structure.md 有详细说明负责应用级配置wasp.version固定 Wasp 编译器版本^0.14.0title用作浏览器标签页标题。注意 Wasp 语言中所有字符串必须使用双引号。当前版本 TodoApp 的对照实现作为对照仓库中已完成的 TodoApp 示例examples/tutorials/TodoApp/main.wasp.ts展示了多路由页面的实际组织方式——除了根路由它还声明了/signup与/login两个认证页面并通过page(MainPage, { authRequired: true })把首页标记为需要登录登录后由src/MainPage.jsxexamples/tutorials/TodoApp/src/MainPage.jsx渲染任务列表。这个结构与你学到的 route/page 声明一一对应可作为后续章节Queries、Actions、Auth的衔接参考。小结本文围绕 Wasp 0.14 的 route 与 page 声明完成了从最小骨架到动态路由、再到脚手架清理的完整闭环route负责 URL 路径page负责 React 组件绑定二者成对出现路径参数用 React Router 同款:param语法组件内通过props.match.params读取TypeScript 用户可用Link组件与routes对象获得类型安全的页面跳转删除页面文件时必须同步删除main.wasp中的对应声明保持声明与源码一致底层由 Wasp 生成器把每条 route 声明编译为 React Router 路由对象见 waspc/data/Generator/templates/sdk/wasp/client/app/router.tsx。至此你已经掌握了 Wasp 中页面与路由的完整工作方式。接下来教程将进入数据库实体Entities的定义——那是 Todo 应用数据层的起点。【免费下载链接】waspThe batteries-included full-stack framework for the AI era. Develop JS/TS web apps (React, Node.js, and Prisma) using declarative code that abstracts away complex full-stack features like auth, background jobs, RPC, email sending, end-to-end type safety, single-command deployment, and more.项目地址: https://gitcode.com/GitHub_Trending/wa/wasp创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表