Flutter路由管理插件shelf_router的使用

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

Flutter路由管理插件shelf_router的使用

简介

shelf_router 是一个用于 Shelf 的请求路由器,它使得构建 Dart 中的 Web 应用程序变得更加容易。通过组合请求处理器,这个包提供了一个基于路由模式匹配请求到处理器的路由器。

pub package package publisher

此外,还有一个名为 shelf_router_generator 的包可以自动生成路由。

示例代码

下面是一个完整的示例,展示了如何使用 shelf_router 创建一个简单的 Web 服务器:

import 'dart:async' show Future;

import 'package:shelf/shelf.dart';
import 'package:shelf/shelf_io.dart' as shelf_io;
import 'package:shelf_router/shelf_router.dart';

class Service {
  // The [Router] can be used to create a handler, which can be used with
  // [shelf_io.serve].
  Handler get handler {
    final router = Router();

    // Handlers can be added with `router.<verb>('<route>', handler)`, the
    // '<route>' may embed URL-parameters, and these may be taken as parameters
    // by the handler (but either all URL parameters or no URL parameters, must
    // be taken parameters by the handler).
    router.get('/say-hi/<name>', (Request request, String name) {
      return Response.ok('hi $name');
    });

    // Embedded URL parameters may also be associated with a regular-expression
    // that the pattern must match.
    router.get('/user/<userId|[0-9]+>', (Request request, String userId) {
      return Response.ok('User has the user-number: $userId');
    });

    // Handlers can be asynchronous (returning `FutureOr` is also allowed).
    router.get('/wave', (Request request) async {
      await Future<void>.delayed(Duration(milliseconds: 100));
      return Response.ok('_o/');
    });

    // Other routers can be mounted...
    router.mount('/api/', Api().router);

    // You can catch all verbs and use a URL-parameter with a regular expression
    // that matches everything to catch app.
    router.all('/<ignored|.*>', (Request request) {
      return Response.notFound('Page not found');
    });

    return router;
  }
}

class Api {
  Future<Response> _messages(Request request) async {
    return Response.ok('[]');
  }

  // By exposing a [Router] for an object, it can be mounted in other routers.
  Router get router {
    final router = Router();

    // A handler can have more than one route.
    router.get('/messages', _messages);
    router.get('/messages/', _messages);

    // This nested catch-all, will only catch /api/.* when mounted above.
    // Notice that ordering if annotated handlers and mounts is significant.
    router.all('/<ignored|.*>', (Request request) => Response.notFound('null'));

    return router;
  }
}

// Run shelf server and host a [Service] instance on port 8080.
void main() async {
  final service = Service();
  final server = await shelf_io.serve(service.handler, 'localhost', 8080);
  print('Server running on localhost:${server.port}');
}

关键点解释

  1. 定义路由:

    • 使用 router.get() 方法来定义 GET 请求的路由。
    • 路由模式中可以包含 URL 参数,例如 /say-hi/<name>/user/<userId|[0-9]+>
  2. 嵌套路由:

    • 使用 router.mount() 方法可以将其他路由挂载到当前路由下,实现模块化路由管理。
  3. 捕获所有请求:

    • 使用 router.all() 方法可以捕获所有未匹配的请求,并返回404页面。
  4. 异步处理:

    • 处理器可以是异步的,例如 router.get('/wave', ...) 中的延迟响应。
  5. 启动服务器:

    • 使用 shelf_io.serve() 启动服务器,并监听指定端口。

参考资料

希望这些信息能帮助你更好地理解和使用 shelf_router 插件!如果你有任何问题或需要进一步的帮助,请随时提问。


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

1 回复

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


当然,下面是一个关于如何在Flutter项目中使用shelf_router插件进行路由管理的示例代码。请注意,shelf_router是一个假设的路由管理插件,因为实际上Flutter中并没有一个名为shelf_router的官方或广泛使用的插件。不过,基于常见的Flutter路由管理插件(如flutter_navigatorflutter_deep_linking),我们可以提供一个类似的示例代码来展示如何在一个Flutter项目中进行路由管理。

首先,确保在你的pubspec.yaml文件中添加路由管理插件的依赖(这里我们假设有一个名为shelf_router的插件,但你需要替换为实际存在的插件,如flutter_navigator等):

dependencies:
  flutter:
    sdk: flutter
  shelf_router: ^x.y.z  # 替换为实际插件的版本号和名称

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

接下来,我们将展示如何在Flutter应用中使用这个假设的shelf_router插件进行路由管理。

主文件(main.dart)

import 'package:flutter/material.dart';
import 'package:shelf_router/shelf_router.dart';  // 假设的插件导入

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      // 使用shelf_router的RouterDelegate和RouteInformationParser
      onGenerateRoute: ShelfRouter.generateRoute,
      routerDelegate: ShelfRouter.delegate(),
    );
  }
}

路由配置(shelf_router.dart)

在这个文件中,我们将定义路由和相应的页面。

import 'package:flutter/material.dart';
import 'package:shelf_router/shelf_router.dart';  // 假设的插件导入
import 'home_page.dart';
import 'details_page.dart';

class ShelfRouter {
  static final routes = <String, WidgetBuilder>{
    '/': (BuildContext context) => HomePage(),
    '/details': (BuildContext context) => DetailsPage(),
  };

  static Route<dynamic> generateRoute(RouteSettings settings) {
    final String? name = settings.name;
    final Function? builder = routes[name];

    if (builder != null) {
      return MaterialPageRoute(builder: builder, settings: settings);
    } else {
      return MaterialPageRoute(
        builder: (BuildContext context) => Scaffold(
          body: Center(
            child: Text('No route defined for ${settings.name}'),
          ),
        ),
      );
    }
  }

  static RouterDelegate<Object> get delegate() {
    return ShellRouterDelegate(
      child: MaterialApp.router(
        routeInformationParser: ShellRouteInformationParser(),
        routerDelegate: ShellRouterDelegate(
          builder: (context, state) {
            return Navigator(
              onGenerateRoute: generateRoute,
            );
          },
        ),
      ),
    );
  }
}

页面定义

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.pushNamed(context, '/details');
          },
          child: Text('Go to Details'),
        ),
      ),
    );
  }
}

details_page.dart

import 'package:flutter/material.dart';

class DetailsPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Details Page'),
      ),
      body: Center(
        child: Text('This is the details page!'),
      ),
    );
  }
}

注意事项

  1. 插件名称:请确保将shelf_router替换为实际存在的路由管理插件的名称。
  2. 路由配置:根据你的应用需求,添加或修改路由配置。
  3. 导航:使用Navigator.pushNamedNavigator.pop等方法进行页面间的导航。

以上代码提供了一个基本的路由管理示例,展示了如何在Flutter应用中使用路由插件进行页面间的导航。如果你使用的是其他具体的路由管理插件,请参考其官方文档进行配置和使用。

回到顶部