Flutter路由管理插件simple_routes的使用

发布于 1周前 作者 ionicwang 来自 Flutter

Flutter路由管理插件simple_routes的使用

simple_routes 是一个用于简化和声明式管理Flutter应用中路由的插件,它与 go_router 配合使用,可以消除魔法字符串,简化路由定义,并提供类型安全的路由管理。

开始使用

首先,在你的 pubspec.yaml 文件中添加依赖:

dependencies:
  go_router: ^6.0.0 # 使用最新版本
  simple_routes: ^1.0.0 # 使用最新版本

然后运行 flutter pub get 来安装这些依赖。

基本用法

简单路由定义

你可以通过继承 SimpleRoute 类来定义路由。例如:

class HomeRoute extends SimpleRoute {
  const HomeRoute() : super('home');
}

要导航到这个路由,可以使用 .go.push 方法:

const HomeRoute().go(context);

带参数的路由

对于需要传递参数的路由,你可以扩展 SimpleDataRoute 类,并定义相应的数据类。例如:

// 定义数据类
class UserRouteData extends SimpleRouteData {
  const UserRouteData({
    required this.userId,
  });

  final String userId;

  @override
  Map<String, String> get parameters => {
    'userId': userId,
  };
}

// 定义路由
class UserRoute extends SimpleDataRoute<UserRouteData> {
  const UserRoute() : super('user/:userId');
}

// 导航时传递数据
const UserRoute().go(
  context,
  data: UserRouteData(userId: '123'),
);

子路由

子路由可以通过实现 ChildRoute 接口来定义。例如:

class UserDetailsRoute extends SimpleDataRoute<UserRouteData> implements ChildRoute<UserRoute> {
  const UserDetailsRoute() : super('details');

  @override
  final UserRoute parent = const UserRoute();
}

这样生成的完整路径将是 /user/:userId/details

GoRouter配置

在配置 GoRouter 时,你可以将自定义的路由类实例传递给 path 参数。例如:

final router = GoRouter(
  initialLocation: const HomeRoute().fullPath(),
  routes: [
    GoRoute(
      path: const HomeRoute().path,
      builder: (context, state) => const HomeScreen(),
    ),
    GoRoute(
      path: const UserRoute().path,
      redirect: (context, state) {
        if (state.pathParameters['userId'] == null) {
          return const HomeRoute().fullPath();
        }
        return null;
      },
      builder: (context, state) {
        final routeData = UserRouteData.fromState(state);
        return UserScreen(userId: routeData.userId);
      },
      routes: [
        GoRoute(
          path: const UserDetailsRoute().path,
          builder: (context, state) {
            final routeData = UserRouteData.fromState(state);
            return UserDetailsScreen(userId: routeData.userId);
          },
        ),
      ],
    ),
  ],
);

导航

一旦路由定义完成并配置好 GoRouter,你就可以使用 .go.push 方法进行导航了。

  • .go 方法会替换当前路由:

    onPressed: () => const HomeRoute().go(context),
    
  • .push 方法会在导航堆栈上推入新路由,并允许返回结果:

    onPressed: () async {
      final result = await const HomeRoute().push(context);
      debugPrint('The result is: $result');
    },
    

完整示例 Demo

下面是一个完整的示例,展示了如何使用 simple_routes 插件来管理路由:

import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:simple_routes/simple_routes.dart';

// 定义路由
class RootRoute extends SimpleRoute {
  const RootRoute() : super('');
}

class DashboardRoute extends SimpleRoute {
  const DashboardRoute() : super('dashboard');
}

class ProfileRoute extends SimpleDataRoute<ProfileRouteData> {
  const ProfileRoute() : super('profile/:userId');
}

class ProfileEditRoute extends SimpleDataRoute<ProfileRouteData> implements ChildRoute<ProfileRoute> {
  const ProfileEditRoute() : super('edit');

  @override
  final ProfileRoute parent = const ProfileRoute();
}

class AdditionalDataRoute extends SimpleDataRoute<AdditionalRouteData> {
  const AdditionalDataRoute() : super('additional');
}

// 定义数据类
class ProfileRouteData extends SimpleRouteData {
  const ProfileRouteData({required this.userId});

  final String userId;

  @override
  Map<String, String> get parameters => {'userId': userId};
}

class AdditionalRouteData extends SimpleRouteData {
  const AdditionalRouteData({required this.userId, required this.queryValue});

  final String userId;
  final String queryValue;

  @override
  Map<String, String> get parameters => {'userId': userId};

  @override
  Map<String, String> get query => {'queryValue': queryValue};
}

// 配置 GoRouter
final router = GoRouter(
  debugLogDiagnostics: true,
  routes: [
    GoRoute(
      path: const RootRoute().path,
      builder: (context, state) => const RootPage(),
      routes: [
        GoRoute(
          path: const DashboardRoute().path,
          builder: (context, state) => const DashboardPage(),
        ),
      ],
    ),
    GoRoute(
      path: const ProfileRoute().path,
      redirect: (context, state) {
        if (state.pathParameters['userId'] == null) {
          return const RootRoute().fullPath();
        }
        return null;
      },
      builder: (context, state) {
        final profileRouteData = ProfileRouteData.fromState(state);
        return ProfilePage(userId: profileRouteData.userId);
      },
      routes: [
        GoRoute(
          path: const ProfileEditRoute().path,
          builder: (context, state) {
            final profileRouteData = ProfileRouteData.fromState(state);
            return ProfileEditPage(userId: profileRouteData.userId);
          },
        ),
        GoRoute(
          path: const AdditionalDataRoute().path,
          builder: (context, state) {
            final additionalRouteData = AdditionalRouteData.fromState(state);
            return AdditionalRouteDataPage(queryValue: additionalRouteData.queryValue);
          },
        ),
      ],
    ),
  ],
);

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp.router(
      routerConfig: router,
      theme: ThemeData.dark(),
      builder: (context, child) => Scaffold(body: child),
    );
  }
}

class NavButtons extends StatelessWidget {
  const NavButtons({super.key});

  @override
  Widget build(BuildContext context) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        const SizedBox(height: 12),
        ElevatedButton(
          onPressed: () => const RootRoute().go(context),
          child: const Text('Go to root'),
        ),
        const SizedBox(height: 12),
        ElevatedButton(
          onPressed: () => const DashboardRoute().go(context),
          child: const Text('Go to dashboard'),
        ),
        const SizedBox(height: 12),
        ElevatedButton(
          onPressed: () => const ProfileRoute().go(
            context,
            data: const ProfileRouteData(userId: '123'),
          ),
          child: const Text('Go to profile'),
        ),
        const SizedBox(height: 12),
        ElevatedButton(
          onPressed: () => const ProfileEditRoute().go(
            context,
            data: const ProfileRouteData(userId: '123'),
          ),
          child: const Text('Go to profile edit'),
        ),
        const SizedBox(height: 12),
        ElevatedButton(
          onPressed: () => const AdditionalDataRoute().go(
            context,
            data: const AdditionalRouteData(userId: '123', queryValue: 'hello world!'),
          ),
          child: const Text('Go to Additional Data route'),
        ),
      ],
    );
  }
}

class RootPage extends StatelessWidget {
  const RootPage({super.key});

  @override
  Widget build(BuildContext context) {
    return const Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        Text('Root'),
        NavButtons(),
      ],
    );
  }
}

class DashboardPage extends StatelessWidget {
  const DashboardPage({super.key});

  @override
  Widget build(BuildContext context) {
    return const Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        Text('Dashboard'),
        NavButtons(),
      ],
    );
  }
}

class ProfilePage extends StatelessWidget {
  const ProfilePage({super.key, required this.userId});

  final String userId;

  @override
  Widget build(BuildContext context) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        Text('Profile for $userId'),
        const NavButtons(),
      ],
    );
  }
}

class ProfileEditPage extends StatelessWidget {
  const ProfileEditPage({super.key, required this.userId});

  final String userId;

  @override
  Widget build(BuildContext context) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        Text('Profile edit page for $userId'),
        const NavButtons(),
      ],
    );
  }
}

class AdditionalRouteDataPage extends StatelessWidget {
  const AdditionalRouteDataPage({super.key, required this.queryValue});

  final String queryValue;

  @override
  Widget build(BuildContext context) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        const Text('Additional Data Route'),
        Text('Query value: $queryValue'),
        const NavButtons(),
      ],
    );
  }
}

这个示例展示了如何使用 simple_routes 插件来定义和管理复杂的路由结构,包括基本路由、带参数的路由以及子路由。希望这对你有所帮助!


更多关于Flutter路由管理插件simple_routes的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter路由管理插件simple_routes的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是一个关于如何在Flutter中使用simple_routes插件进行路由管理的代码示例。simple_routes是一个用于简化Flutter应用中的路由管理的插件。

首先,你需要在你的pubspec.yaml文件中添加simple_routes依赖:

dependencies:
  flutter:
    sdk: flutter
  simple_routes: ^x.y.z  # 请替换为最新版本号

然后运行flutter pub get来安装依赖。

接下来,我们可以开始配置路由。假设我们有两个页面:HomePageSecondPage

  1. 创建页面文件:

home_page.dart

import 'package:flutter/material.dart';

class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Home Page'),
      ),
      body: Center(
        child: ElevatedButton(
          onPressed: () {
            Navigator.of(context).pushNamed('/second');
          },
          child: Text('Go to Second Page'),
        ),
      ),
    );
  }
}

second_page.dart

import 'package:flutter/material.dart';

class SecondPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Second Page'),
      ),
      body: Center(
        child: Text('This is the second page'),
      ),
    );
  }
}
  1. 配置路由:

创建一个新的文件routes.dart来配置路由:

import 'package:flutter/material.dart';
import 'package:simple_routes/simple_routes.dart';
import 'home_page.dart';
import 'second_page.dart';

class MyRouter {
  static final MyRouter _singleton = MyRouter._internal();

  factory MyRouter() => _singleton;

  MyRouter._internal();

  SimpleRoutes get routes => SimpleRoutes(
        routes: {
          '/': (context, args) => HomePage(),
          '/second': (context, args) => SecondPage(),
        },
      );
}
  1. main.dart中使用路由:
import 'package:flutter/material.dart';
import 'package:simple_routes/simple_routes.dart';
import 'routes.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      navigatorKey: SimpleRoutes.navigatorKey, // 必须设置这个key
      onGenerateRoute: MyRouter().routes.generator, // 使用生成的路由
    );
  }
}

以上代码完成了以下几步:

  1. 添加了simple_routes依赖。
  2. 创建了两个页面:HomePageSecondPage
  3. routes.dart中配置了路由。
  4. main.dart中设置了MaterialApp,并将路由生成器传递给onGenerateRoute

这样,你就可以在Flutter应用中使用simple_routes插件进行路由管理了。点击HomePage中的按钮将导航到SecondPage

回到顶部