1. 介绍
路由可帮助我们在应用页面之间导航,它们通常从 ( /
) 索引页提供导航。您可以在 lib/routers/router.dart
文件内添加路由。路由是使用路由名称构建的,例如, "/settings"
然后提供您想要显示的小部件。
dart
appRouter() => nyRoutes((router) {
...
router.route(SettingsPage.path, (context) => SettingsPage());
// 添加更多
// router.route(HomePage.path, (context) => HomePage());
});
在 Nylo 中,您可能还需要将数据从一个视图传递到另一个视图,可以使用 NyStatefulWidget
。
2. 添加路由
运行以下命令以创建新页面。
dart run nylo_framework:main make:page profile_page
运行上述内容后,它将创建一个新的名为 ProfilePage
页面并将其添加到resources/pages/
目录中。它还会将新路由添加到 lib/routes/router.dart
文件中。
/lib/routes/router.dart
dart
appRouter() => nyRoutes((router) {
...
router.route(HomePage.path, (context) => HomePage(), initialRoute: true);
// 新路由
router.route(ProfilePage.path, (context) => ProfilePage());
});
3. 导航到页面
您可以使用该 Navigator
类导航到新页面,如下例所示。
dart
void _pressedSettings() {
Navigator.pushNamed(context, SettingsPage.path);
}
如果您的小部件扩展了类, NyState
也可以使用 routeTo()
进行导航。
dart
import 'package:nylo_framework/nylo_framework.dart';
class SettingsPage extends StatefulWidget {
@override
_SettingsPageState createState() => _SettingsPageState();
}
class _SettingsPageState extends NyState<SettingsPage> {
void _pressedSettings() {
routeTo(SettingsPage.path);
}
...
4. 多个路由器
如果您的 routes/router.dart
文件太大,或者您需要分离路由,则可以使用多个路由。首先,在新文件中定义路由,如以下示例所示。
/lib/routes/dashboard_router.dart
dart
NyRouter dashboardRouter() => nyRoutes((router) {
// 将路由添加到这里
router.route("/account", (context) => AccountPage());
router.route(AccountUpdatePage.path, (context) => AccountUpdatePage());
});
然后,打开 /lib/app/providers/route_provider.dart
并添加新路由器。
dart
import'package:flutter_app/routes/router.dart';
import'package:flutter_app/routes/dashboard_router.dart';
import'package:nylo_framework/nylo_framework.dart';
classRouteProviderimplementsNyProvider{
boot(Nylo nylo) async {
nylo.addRouter(appRouter());
nylo.addRouter(dashboardRouter()); // new routesreturn nylo;
}
}
...
5. 初始路由
在路由器中,您可以通过将 initialRoute
参数传递给要使用的路由来将寻呼设置为初始路由。
下面是一个示例。
dart
appRouter() => nyRoutes((router) {
router.route(
HomePage.path,
(context) => HomePage(title: "Hello World")
);
router.route(
SettingsPage.path,
(context) => SettingsPage()
);
router.route(
ProfilePage.path,
(context) => ProfilePage(), initialRoute: true // 初始路由
);
});
6. 路线守卫
路线守卫会阻止或允许用户访问该页面(如果他们获得授权)。
下面是一个示例。
dart
// 1 - /routes/router.dart
appRouter() => nyRoutes((router) {
router.route(
HomePage.path,
(context) => HomePage()
);
router.route(
DashboardPage.path,
(context) => DashboardPage()
); // 受限页面
router.route(
LoginPage.path,
(context) => LoginPage(),
);
});
// 2 - /routes/guards/auth_route_guard.dart
// 创建一个新的路由守卫
class AuthRouteGuard extends NyRouteGuard {
AuthRouteGuard();
@override
Future<bool> canOpen(BuildContext? context, NyArgument? data) async {
// 检查他们是否可以访问页面
return (await Auth.loggedIn());
}
@override
redirectTo(BuildContext? context, NyArgument? data) async {
// 设置重定向页面
await routeTo(HomePage.path);
}
}
// 3 - /routes/router.dart
// 添加一个新的路由守卫
appRouter() => nyRoutes((router) {
router.route(
HomePage.path,
(context) => HomePage()
);
router.route(
DashboardPage.path,
(context) => DashboardPage(),
routeGuards: [
AuthRouteGuard()
]
); // 受限页面
router.route(
LoginPage.path,
(context) => LoginPage(),
);
});
创建新的路由防护时,请将其添加到目录中 /routes/guards/
。
使用Metro CLI 创建新的路由防护。
dart run nylo_framework:main make:route_guard subscription
7. 将数据传递到另一个页面
在本节中,我们将展示如何将数据从一个小部件传递到另一个小部件。有时,使用 Navigator
类发送数据可能很有用,但也可以使用 routeTo
。
dart
// HomePage Widget
void _pressedSettings() {
Navigator.pushNamed(context, SettingsPage.path, arguments: "Hello World");
// 或者
routeTo(SettingsPage.path, data: "Hello World");
}
...
// SettingsPage Widget (other page)
class _SettingsPageState extends NyState<SettingsPage> {
...
@override
init() async {
print(widget.data()); // Hello World
}
更多示例
dart
// Home page widget
class _HomePageState extends NyState<HomePage> {
_showProfile() {
User user = new User();
user.firstName = 'Anthony';
routeTo(ProfilePage.path, data: user);
}
...
// Profile page
class _ProfilePageState extends NyState<ProfilePage> {
@override
init() {
User user = widget.data();
print(user.firstName);
}
8. 查询参数
导航到新页面时,可以提供查询参数。
dart
// Home page
Navigator.pushNamed(context, '${ProfilePage.path}?user=7'); // 导航到profile
...
// Profile Page
@override
init() async {
print(widget.queryParameters()); // {"user": 7}
}
只要页面小部件扩展了 NyStatefulWidget
和 NyState
类,就可以调用 widget.queryParameters()
以从路由名称中获取所有查询参数。
dart
// Example page
Navigator.pushNamed(context, '${HomePage.path}?hello=world&say=I%20love%20code');
...
// Home page
class MyHomePage extends NyStatefulWidget {
...
}
class _MyHomePageState extends NyState<MyHomePage> {
@override
init() async {
print(widget.queryParameters()); // {"hello": "World", "say": "I love code"}
}
查询参数必须遵循 HTTP 协议,例如 /accountuserId=1&tab=2
9. 页面过渡
可以通过修改 router.dart
文件在从一个页面导航时添加过渡效果。
dart
import 'package:page_transition/page_transition.dart';
appRouter() => nyRoutes((router) {
// bottomToTop
router.route(
SettingsPage.path, (context) => SettingsPage(),
transition: PageTransitionType.bottomToTop
);
// leftToRightWithFade
router.route(
HomePage.path, (context) => HomePage(),
transition: PageTransitionType.leftToRightWithFade
);
});
可用过渡:
- PageTransitionType.fade
- PageTransitionType.rightToLeft
- PageTransitionType.leftToRight
- PageTransitionType.topToBottom
- PageTransitionType.bottomToTop
- PageTransitionType.scale (带对齐方式)
- PageTransitionType.rotate (带对齐方式)
- PageTransitionType.size (带对齐方式)
- PageTransitionType.rightToLeftWithFade
- PageTransitionType.leftToRightWithFade
- PageTransitionType.leftToRightJoined
- PageTransitionType.rightToLeftJoined
还可以在导航到项目中的新页面时应用过渡。
dart
// Home page widget
class _HomePageState extends NyState<HomePage> {
_showProfile() {
routeTo(
ProfilePage.path,
pageTransition: PageTransitionType.bottomToTop
);
}
...
Nylo使用page_transition使这成为可能。
10. 导航类型
导航时,如果使用的是 routeTo
,则可以指定以下内容之一。
- NavigationType.push - 将新页面推送到应用的路由堆栈.
- NavigationType.pushReplace - 换当前路由,一旦新路由完成,该路由将释放以前的路由.
- NavigationType.popAndPushNamed - 将当前路由从导航器中弹出,并将命名路由推送到其位置.
- NavigationType.pushAndForgetAll - 推送到新页面并处理堆栈上的任何其他页面.
dart
// Home page widget
class _HomePageState extends NyState<HomePage> {
_showProfile() {
routeTo(
ProfilePage.path,
navigationType: NavigationType.pushReplace
);
}
...
11. 返回
进入新页面后,可以使用 pop()
帮助程序返回到现有页面。
dart
// SettingsPage Widget
class _SettingsPageState extends NyState<SettingsPage> {
_back() {
this.pop();
// or
Navigator.pop(context);
}
...
如果要将值返回给上一个小部件,可以提供与以下示例中的 result
类似的值。
dart
// SettingsPage Widget
class _SettingsPageState extends NyState<SettingsPage> {
_back() {
pop(result: {"status": "COMPLETE"});
}
...
// 然后使用 `onPop` 参数从之前的 widget 获取值
// HomePage Widget
class _HomePageState extends NyState<HomePage> {
_viewSettings() {
routeTo(SettingsPage.path, onPop: (value) {
print(value); // {"status": "COMPLETE"}
});
}
...
12. 身份验证页面
可以将路由设置为"auth page ",这将使该路由在打开应用程序时成为默认的初始路由。首先,应使用 Auth.set(user)
记录用户。
一旦他们被添加到身份验证,下次他们访问应用程序时,它将使用身份验证页面而不是默认索引页面。
dart
appRouter() => nyRoutes((router) {
router.route(HomePage.path, (context) => HomePage(title: "Hello World"));
router.route(ProfilePage.path, (context) => ProfilePage(), authPage: true); // auth page
});
下列教程会有专门的章节讲解身份校验。