VRouter logo

VRouter website
Join our discord
Github repo
pub package


一个让导航和路由变得容易的 Flutter 包。

vrouter.dev 了解更多

该包将使以下方面变得容易

  • 自动化的 Web URL 处理
  • 嵌套路由
  • 过渡
  • 高级 URL 命名
  • 路由变化响应
  • 可自定义的弹出事件
  • 还有更多…

目录

入门

VRouter

VRouter 是一个处理导航的小部件,它充当 MaterialApp,但也接受一个 routes 参数。

VRouter(
 debugShowCheckedModeBanner: false, // VRouter acts as a MaterialApp
 routes: [...], // Put your VRouteElements here
)

VRouteElements

VRouteElements 是你路由的构建块。

请注意,它们不是小部件,但使用方式与小部件非常相似

VWidget

VWidget 将路径映射到一个小部件。

VWidget(path: '/login', widget: LoginScreen())

VGuard

VGuard 允许你在访问/离开路由时执行操作。

VGuard(
 beforeEnter: (vRedirector) async => , // Triggered when a route in stackedRoutes is first displayed
 beforeUpdate: (vRedirector) async => , // Triggered when a route in stackedRoutes is displayed but changes
 beforeLeave: (vRedirector, _) async => , // Triggered when VGuard is not part of a new route
 stackedRoutes: [...],
);

VRouteRedirector

VRouteRedirector 将一个路由重定向到另一个。

VRouteRedirector(path: '/old/home', redirectTo: '/home')

VNester

当你需要嵌套小部件而不是堆叠它们时,会使用 VNester

VNester(
 path: '/home',
 widgetBuilder: (child) => MyScaffold(body: child), // child will take the value of the widget in nestedRoutes
 nestedRoutes: [
   VWidget(path: 'profile', widget: ProfileScreen()), // path '/home/profile'
   VWidget(path: 'settings', widget: SettingsScreen()), // path '/home/settings'
 ],
)

VPopHandler

VPopHandler 帮助你控制弹出事件。

VPopHandler(
 onPop: (vRedirector) async =>, // Called when this VRouteElement is popped
 onSystemPop: (vRedirector) async =>, // Called when this VRouteElement is popped by android back button
 stackedRoutes: [...],
)

导航

导航很简单,只需使用 context.vRouter 访问 VRouter 并进行导航。

context.vRouter.to('/home'); // Push the url '/home'

context.vRouter.toSegments(['home', 'settings']); // Push the url '/home/settings'

实用概念

组合

VRouteElement 的设计类似于小部件:将它们组合起来创建你需要的路由。

组合 VRouteElements

要组合 VRouteElement,请使用 stackedRoutes 属性(或 VNesternestedRoutes 属性)。

// Composing a VGuard and a VWidget
VGuard(
 beforeEnter: (vRedirector) async => !isLoggedIn ? vRedirector.to('/login') : null,
 stackedRoutes: [
   VWidget(path: '/home', widget: HomeScreen()),
 ],
)

创建自定义 VRouteElements

你甚至可以创建自己的 VRouteElement,就像扩展 VWidget 一样。你只需要扩展 VRouteElementBuilder

class HomeRoute extends VRouteElementBuilder {
 static String home = '/home';

 @override
 List<VRouteElement> buildRoutes() {
   return [
     VGuard(
       // LoginRoute.login = '/login' for example
       beforeEnter: (vRedirector) async => !isLoggedIn ? vRedirector.to(LoginRoute.login) : null,
       stackedRoutes: [
         VWidget(path: home, widget: HomeScreen()),
       ],
     ),
   ];
 }
}

然后像使用其他任何元素一样使用这个 VRouteElement

VRouter(
 routes: [
   HomeRoute(),
   ...
 ],
)

这可以用于

  • 将不同的路由分离到不同的 VRouteElement 中
  • 创建可重用的 VRouteElement
  • 使用 static String 来组织你的路径

注意:你通常希望在不同的 VRouteElementBuilder 中使用共享的 VNester,对于这种情况,请参阅 vrouter.dev/Custom VRouteElement And Scaling

路径

相对路径

路径可以是相对的:如果你不以 / 开头。如果你使用 null,路径将是父路径。

VNester(
 path: '/home',
 widgetBuilder: (child) => MyScaffold(body: child),
 nestedRoutes: [
   VWidget(path: null, widget: HomeScreen()), // Matches '/home'
   VWidget(path: 'settings', widget: SettingsScreen()), // Matches '/home/settings'
 ]
)

路径参数

路径可以包含路径参数,只需在参数名称前加上“:”即可。

VWidget(path: '/user/:id', widget: UserScreen())

并在你的部件中通过以下方式访问它:

context.vRouter.pathParameters['id'];

通配符

通配符用 * 表示,它们有两种类型:

  • 以 * 结尾的尾部通配符将匹配所有内容。
  • 位于斜杠之间的路径内通配符将匹配一个单词。

// Redirects any path to '/unknown'
VRouteRedirector(path: '*', redirectTo: '/unknown')

路径参数正则表达式

路径参数可以使用正则表达式,只需将正则表达式放在括号中。这通常在 VRedirector 中用于重定向任何未知的路由。

// The path parameter name is “bookId” and it uses the regex “\d+” to match only digits
VWidget(path: r':bookId(\d+)', widget: BookScreen())

请注意,这样的 VRedirector 应该作为你的最后一个 route 使用,否则它将始终被匹配。

别名

为多个路径使用别名。:

// Matches '/settings' and '/other'
VWidget(path: '/settings', aliases: ['/other'], widget: SettingsScreen())

VRedirector

你经常需要在 VGuardVPopHandler 中重定向或停止当前重定向。为此,你会得到一个 VRedirector

VGuard(
 beforeEnter: (vRedirector) async => !isLoggedIn ? vRedirector.to('/login') : null,
 stackedRoutes: [...],
)

VRouterData

VRouter 包含数据(例如路径或路径参数),你可能希望在小部件树中访问它们。有两种方法可以做到:

// Use the context
context.vRouter

// Use the builder constructor of some VWidget or VNester
VWidget.builder(
  path: '/:id', 
  builder: (context, state) => Book(id: state.pathParameters['id'] as int),
)

更进一步

我们才刚刚接触 VRouter 的表面。以下是您可能喜欢的一些其他功能。

初始 URL

也许你想在用户首次启动应用时将他们重定向到应用的某个部分,然后使用 initialUrl

VRouter(
 initialUrl: '/home',
 routes: [...],
)

日志

默认情况下,VRouter 会显示每个导航事件的日志。

你可以使用 VLogs.none 移除这些日志。

VRouter(
  logs: VLogs.none,
  routes: [...],
);

命名路由

你可能需要访问一个深度嵌套的 VRouteElement,并且不想编写完整的 URL。只需为该 VRouteElement 指定一个名称。

VWidget(path: 'something', widget: SomeWidget(), name: 'deep')

然后使用 toNamed 进行导航。

context.vRouter.toNamed('deep');

过渡

你可以在 VRouter 中指定默认过渡,或在 VWidgetVNester 中指定自定义过渡。

VRouter(
 // Default transition
 buildTransition: (animation1, _, child) => FadeTransition(opacity: animation1, child: child),
 routes: [
   // The custom ScaleTransition will play for '/user'
   VWidget(
     path: '/user',
     widget: UsersScreen(),
     buildTransition: (animation1, _, child) => ScaleTransition(scale: animation1, child: child),
   )
   // The default FadeTransition will play for '/settings'
   VWidget(path: '/settings', widget: SettingsScreen()),
 ],
)

更多

这个包还有很多功能,可以查看示例。
或者查看 vrouter.dev 网站以获取更多文档和示例。

也请随时 加入我们的 Discord

GitHub

https://github.com/lulupointu/vrouter