パッケージ、リポジトリ、アプリカテゴリを検索

パッケージ詳細v4.1.1

go_router_plus

ビルディングブロックスクリーン、Go Routerに基づくアクセス制御およびリフレッシュ通知子。

AndroidiOSWebmacOSWindowsLinux
30日間ダウンロード
107
いいね数
30
Pub ポイント
130

パッケージをインストール

flutter pub add go_router_plus

パッケージ概要

公開情報に基づく選定ガイドです。参考としてご利用ください。

go_router_plus は Go Router を基盤として、モジュール化された画面定義、ロールベースのアクセス制御、および内蔵の通知機能による自動状態更新を提供する拡張ルーティング機能を備えています。複雑なルーティングロジックを再利用可能なコンポーネントに抽象化することで、Flutterアプリにおけるナビゲーションを簡素化します。このパッケージはすべての主要プラットフォームをサポートしており、動的なアクセス要件とリアルタイムのUI更新を必要とするスケーラブルで保守しやすいアプリケーションに最適です。最小限のボイラープレートで構造的なルーティングアプローチを求める開発者向けに設計されています。

用途

  • 動的ルートを持つ単一ページアプリケーション
  • マルチロールユーザーのダッシュボード
  • リフレッシュ通知子によるリアルタイムUIの更新
  • モジュラーアプリケーションアーキテクチャ
  • クロスプラットフォームルーティングの整合性
  • 保護されたルート処理

主な機能

  • モジュラースクリーン定義
  • ロールベースのアクセス制御
  • 組み込みの更新通知
  • プラットフォームに依存しないルーティング
  • 拡張可能なルート構成
  • Go Router との簡単な統合

適している対象

  • スケーラブルなFlutterアプリを開発する開発者
  • 集中ルーティング論理を必要とするチーム
  • 複雑なアクセス制御を持つアプリ
  • 自動UIリフレッシュを必要とするプロジェクト
  • 複数のプラットフォーム向けのFlutterアプリ

注意事項

  • Go Router に精通している必要があります
  • バンドルサイズがわずかに増える可能性があります
  • 外部の状態管理パターンに依存しています
  • 中〜大規模なプロジェクトに最適
  • 基本的なセットアップを超えるドキュメントは限られている

元の README

関連するソースリポジトリの README 原文のスナップショットです。最新の内容はリポジトリをご覧ください。

Go Router Plus

CI codecov GitHub license

Go Router is an awesome easy-to-use and production ready package for creating routes, handling navigation, deep and dynamic links but in large apps have a lot of screens, states and auth logics, it's hard to manage routes, redirect and refresh router logics.

This package try to solve problems above by adding screen pattern, common redirect logics and chain redirect/refresh listenable.

Installation

Run the command bellow to install this package:

flutter pub add go_router_plus

After install pub package, now you can import it:

import 'package:go_router_plus/go_router_plus.dart';

Creating screens

Screen represent for route of your application, the purpose of it is separate GoRoute factory logics out of GoRouter factory for easy-to-read and maintaining.

/// lib/screens/my_first_screen.dart

import 'package:go_router_plus/go_router_plus.dart';
import 'package:go_router/go_router.dart'

class MyFirstScreen extends Screen {
  @override
  Widget build(BuildContext context, GoRouterState state) {
    return Text('Hello world');
  }

  @override
  String get routeName => 'my_first_screen';

  @override
  String get routePath => '/my-first-screen';
}

All of your screens must be extends an abstraction class Screen providing by this package. The following methods, getters need to implements:

  • Method build(BuildContext context, GoRouterState state) must be redeclare return type to Widget or Page<void>, in common case you should use Widget but if you want to control the transition of screen you should use Page<void>.
  • Getter routeName declare route name of the screen must be unique.
  • Getter routePath declare route path of the screen.
Mark screen as an initial screen

To setup initial path (the first screen user will see) in traditional way, we will set initialPath argument of GoRouter factory but when using this package you need to create the screen implements InitialScreen interface instead.

class LoginScreen extends Screen implements InitialScreen {
  ///......
}
Mark screen as an error screen

As you know, GoRouter factory offer we an errorBuilder argument to handling error (e.g route not found) but when using this package you need to create the screen implements ErrorScreen interface instead.

class MyErrorScreen extends Screen implements ErrorScreen {
  @override
  Widget build(BuildContext context, GoRouterState state) {
    return Text(state.error);
  }
  ///......
}
Nested navigation

ShellRoute was added since go router v5 provides a way to wrap all sub-routes with a UI shell. Under the hood, GoRouter places a Navigator in the widget tree, which is used to display matching sub-routes, you can use this feature by extends ShellScreen class:

class MyShellScreen extends ShellScreen {
 @override
 List<ScreenBase> subScreens() {
  return [
   ScreenA(),
   ScreenB(),
  ];
 }
}
Creating router with screens

Now you got the screen pattern concept, let creating Go Router:

final router = createGoRouter(
  screens: [
    LoginScreen(),
    MyFirstScreen(),
    MyErrorScreen(),
  ],
);

createGoRouter factory function providing by this package.

Redirector

Redirector will handles redirection logics of all routes.

You can setup one or many redirectors via redirectors argument of createGoRouter factory function:

final router = createGoRouter(
  screens: [
    LoginScreen(),
    MyFirstScreen(),
    MyErrorScreen(),
  ],
  redirectors: [
    AuthRedirector(
     state: LoggedInStateProvider(),
     guestRedirectPath: '/login',
     userRedirectPath: '/home-page',
    ),
    ScreenRedirector(),
  ],
);
Authentication redirection

Authentication redirection is the most of common logic of the whole app so it provided out of the box by this package via AuthRedirector.

To use this builtin feature, you need to create a class implements the LoggedInState interface:

class LoggedInStateProvider implements LoggedInState {
  bool _loggedIn = false;
  
  @override
  bool get loggedIn => _loggedIn;
  
  set loggedIn(bool value) {
    _loggedIn = value;
  }
}

It's a simple interface need you implements loggedIn getter, this getter return true when user has been logged in otherwise user's guest (not logged in).

And you need to marks guest and user screens of you app by using UserScreen and GuestScreen interfaces:

class LoginScreen extends Screen implements GuestScreen {
 @override
 String get routePath => '/login';
 ///...
}

class HomeScreen extends Screen implements UserScreen {
 @override
 String get routePath => '/home';
  ///...
}

In example above, we have two screen, one for guest (login screen) and one for user (home screen). When user is NOT logged in he/she will be redirect to login screen otherwise he/she will redirect to home screen, to handling this scenario, we need to add AuthRedirector with the setting bellow:

final router = createGoRouter(
  screens: [
    LoginScreen(),
    HomeScreen(),
  ],
  redirectors: [
    AuthRedirector(
     state: LoggedInStateProvider(),
     guestRedirectPath: '/login',
     userRedirectPath: '/home',
    ),
  ],
);

Now everytime user access to screens implements UserScreen interface but he/she's NOT logged in will be redirect to login screen and if they access to screens implements GuestScreen interface but logged in will be redirect to home screen.

Screen redirection

It's a builtin feature to support screens have a custom redirect logic (e.g: access control by app states, user roles).

Screens want to build custom redirect logic should be implements RedirectAware:

class VipScreen extends Screen implements UserScreen, RedirectAware {
 @override
 FutureOr<String?> redirect(BuildContext context, GoRouterState state) {
   /// final currentUser = ....
   return !currentUser.isVip ? '/home' : null; 
 }
}

Like origin redirection, redirect method above return null in case current user's VIP type so user can stay in this screen, on the other hand normal user will be redirect to home screen.

And to activate this feature pass ScreenRedirector instance to redirectors argument of factory function:

final router = createGoRouter(
  screens: [
    LoginScreen(),
    HomeScreen(),
    VipScreen(),
  ],
  redirectors: [
    ScreenRedirector(),
    AuthRedirector(
     state: LoggedInStateProvider(),
     guestRedirectPath: '/login',
     userRedirectPath: '/home',
    ),
  ],
);
Creating custom redirector

In some cases, you may want to control redirection logics for common screens like AuthRedirector or ScreenRedirector above (e.g: add an interface to marks some screens only admin user can access).

abstract class AdminScreen {}

class ManageUserScreen extends Screen implements AdminScreen {
  ///...
}

class AdminRedirector implements RestrictRedirector {
 @override
 bool shouldRedirect(Screen screen) {
   return screen is AdminScreen;
 }

 @override
 FutureOr<String?> redirect(BuildContext context, GoRouterState state) {
  /// final currentUser = ....
  return !currentUser.isAdmin ? '/home' : null;
 }
}

In the example above, we have add the AdminScreen interface use to marks screens for admin user only, if user's not permit will be redirect to home screen.

AdminRedirector implements RestrictRedirector interface only execute redirect method when shouldRedirect method return true otherwise it'll skip. In this case, shouldRedirect method only return true when current screen implements AdminScreen.

The final step is add custom redirector to redirectors argument of factory function

final router = createGoRouter(
 screens: [
  ManageUserScreen(),
 ],
 redirectors: [
  AdminRedirector(),
  ///...
 ],
);

Refresh notifiers

Refresh listenable is a builtin feature of GoRouter to re-invoke redirection logics but it only accept one listenable and we need to implements all of re-invoke logics in one place.

With this package you can add more than one listenable to re-invoke redirection logics so you can separate logics to easy control, readable and independent to each others.

Pass one or more listenable instance to refreshNotifiers argument of factory function:

class AuthService with ChangeNotifier implements LoggedInState {
  bool _loggedIn = true;
  
  @override
  bool loggedIn() => _loggedIn;
  
  void logout() {
    _loggedIn = false;
    notifyListeners();
  }
}

class PromotionService with ChangeNotifer {
 void activate() {
  ///....
  notifyListeners();
 }
}

final authService = AuthService();
final router = createGoRouter(
 screens: [
  ManageUserScreen(),
 ],
 redirectors: [
  AuthRedirector(
   state: authService,
   guestRedirectPath: '/login',
   userRedirectPath: '/home',
  ),
  ///...
 ],
 refreshNotifiers: [
  authService,
  PromotionService(),
  /// GoRouterRefreshStream(...),
 ]
);

In the example above, AuthService class's a refresh notifier and implements LoggedInState interface to providing state of current user's logged-in or guest. When user logout AuthRedirector will invoke and redirect he/she to login screen. In the other hand, promotion service will invoke redirection logic when activate promotion (e.g: move user to promotion screen).

カテゴリー

依存関係

依存関係一覧 2 件

ソースリポジトリ

このパッケージを使用しているプロジェクト

データはまだありません。