Flutter微框架Nylo(二):路由

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}
}

只要页面小部件扩展了 NyStatefulWidgetNyState 类,就可以调用 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
});

下列教程会有专门的章节讲解身份校验。

相关推荐
满分观察网友z几秒前
uniapp的navigator跳转功能
前端
江城开朗的豌豆5 分钟前
Vue组件DIY指南:手把手教你玩转自定义组件
前端·javascript·vue.js
无奈何杨9 分钟前
CoolGuard风控节假日完善,QLExpress自定义函数
前端·后端
程序员江同学10 分钟前
Kotlin/Native 编译流程浅析
android·kotlin
Daniel_Coder29 分钟前
iOS Widget 开发-1:什么是 iOS Widget?开发前的基本认知
ios·swiftui·swift·widget
CSR-kkk29 分钟前
前端工程化速通——①ES6
前端·es6·速通
yt9483234 分钟前
C#实现CAN通讯接口
java·linux·前端
前端小巷子35 分钟前
Cookie与Session:Web开发中的身份验证与数据存储
前端·javascript·面试
小磊哥er1 小时前
【前端工程化】前端开发中如何做一套规范的项目模版
前端