Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

定义路由

Defining Routes

入门

Getting Started

使用这个路由管理器入门很容易。

It’s easy to get started with the router.

首先,确保你已将 leptos_router 包添加到依赖项中。与 leptos 不同,它没有单独的 csrhydrate 特性;它确实有一个 ssr 特性,仅限在服务端使用,因此请在你的服务端构建中激活它。

First things first, make sure you’ve added the leptos_router package to your dependencies. Unlike leptos, this does not have separate csr and hydrate features; it does have an ssr feature, intended for use only on the server side, so activate that for your server-side build.

重要的是,路由管理器是一个独立于 leptos 本身的包。这意味着路由管理器中的所有内容都可以在用户层代码中定义。如果你想创建自己的路由管理器,或者不使用路由管理器,你完全可以自由地这样做!

It’s important that the router is a separate package from leptos itself. This means that everything in the router can be defined in user-land code. If you want to create your own router, or use no router, you’re completely free to do that!

并从路由管理器中导入相关的类型,可以像这样导入:

And import the relevant types from the router, either with something like

use leptos_router::components::{Router, Route, Routes};

提供 <Router/>

Providing the <Router/>

路由行为由 <Router/> 组件提供。它通常应该位于应用程序根目录附近,包裹住应用的其余部分。

Routing behavior is provided by the <Router/> component. This should usually be somewhere near the root of your application, wrapping the rest of the app.

你不应该在应用中尝试使用多个 <Router/>。请记住,路由管理器驱动全局状态:如果你有多个路由管理器,当 URL 改变时,由哪一个来决定要做什么呢?

You shouldn’t try to use multiple <Router/>s in your app. Remember that the router drives global state: if you have multiple routers, which one decides what to do when the URL changes?

让我们从一个使用路由管理器的简单 <App/> 组件开始:

Let’s start with a simple <App/> component using the router:

use leptos::prelude::*;
use leptos_router::components::Router;

#[component]
pub fn App() -> impl IntoView {
    view! {
      <Router>
        <nav>
          /* ... */
        </nav>
        <main>
          /* ... */
        </main>
      </Router>
    }
}

定义 <Routes/>

Defining <Routes/>

<Routes/> 组件是你定义用户在应用程序中可以导航到的所有路由的地方。每个可能的路由都由一个 <Route/> 组件定义。

The <Routes/> component is where you define all the routes to which a user can navigate in your application. Each possible route is defined by a <Route/> component.

你应该将 <Routes/> 组件放置在应用中你希望渲染路由的位置。<Routes/> 之外的所有内容都将显示在每个页面上,因此你可以将导航栏或菜单之类的东西留在 <Routes/> 之外。

You should place the <Routes/> component at the location within your app where you want routes to be rendered. Everything outside <Routes/> will be present on every page, so you can leave things like a navigation bar or menu outside the <Routes/>.

use leptos::prelude::*;
use leptos_router::components::*;

#[component]
pub fn App() -> impl IntoView {
    view! {
      <Router>
        <nav>
          /* ... */
        </nav>
        <main>
          // 我们所有的路由都会出现在 <main> 内部
          // all our routes will appear inside <main>
          <Routes fallback=|| "Not found.">
            /* ... */
          </Routes>
        </main>
      </Router>
    }
}

<Routes/> 还应该有一个 fallback,这是一个定义如果没有匹配到路由时应该显示什么的函数。

<Routes/> should also have a fallback, a function that defines what should be shown if no route is matched.

通过使用 <Route/> 组件为 <Routes/> 提供子组件来定义单个路由。<Route/> 接受一个 path 和一个 view。当当前位置匹配 path 时,view 将被创建并显示。

Individual routes are defined by providing children to <Routes/> with the <Route/> component. <Route/> takes a path and a view. When the current location matches path, the view will be created and displayed.

使用 path 宏可以最轻松地定义 path,它可以包括:

The path is most easily defined using the path macro, and can include

  • 静态路径(/users),

  • 以冒号开头的动态命名参数(/:id),

  • 以及/或者以星号开头的通配符(/user/*any

  • a static path (/users),

  • dynamic, named parameters beginning with a colon (/:id),

  • and/or a wildcard beginning with an asterisk (/user/*any)

view 是一个返回视图的函数。任何没有属性(props)的组件都可以在这里工作,返回某些视图的闭包也可以。

The view is a function that returns a view. Any component with no props works here, as does a closure that returns some view.

<Routes fallback=|| "Not found.">
  <Route path=path!("/") view=Home/>
  <Route path=path!("/users") view=Users/>
  <Route path=path!("/users/:id") view=UserProfile/>
  <Route path=path!("/*any") view=|| view! { <h1>"Not Found"</h1> }/>
</Routes>

view 接受一个 Fn() -> impl IntoView。如果一个组件没有属性(props),它可以直接传递到 view 中。在这种情况下,view=Home 只是 view=|| view! { <Home/> } 的简写。

view takes a Fn() -> impl IntoView. If a component has no props, it can be passed directly into the view. In this case, view=Home is just a shorthand for view=|| view! { <Home/> }.

现在,如果你导航到 //users,你将获得主页或 <Users/>。如果你去 /users/3/blahblah,你将获得用户个人资料或你的 404 页面(<NotFound/>)。在每次导航时,路由管理器都会确定应该匹配哪个 <Route/>,从而确定在定义 <Routes/> 组件的位置应该显示什么内容。

Now if you navigate to / or to /users you’ll get the home page or the <Users/>. If you go to /users/3 or /blahblah you’ll get a user profile or your 404 page (<NotFound/>). On every navigation, the router determines which <Route/> should be matched, and therefore what content should be displayed where the <Routes/> component is defined.

足够简单吧?

Simple enough?