【Flutter Web】ルーティング対応で画面にURLをつける

こんにちは:laughing:
今回はFlutterWebの以下のようなルーティング対応を実装していきます！
![routemaster.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3524120/614df95e-fe9d-9cbc-5b33-7e7d1535418b.gif)


- 私が試したもの
    - 名前付きルートを使う
    - fluro
    - go_router
    - routemaster

以上の4つを試しました！

その中で、非常に簡単で柔軟性があると思ったRouteMasterを紹介していきます。

#目次
[1.はじめに](#1-はじめに)
[2.パッケージ](#2-パッケージ)
[3.main.dart](#3-main.dart)
[4.page_one.dart](#4-page_one.dart)
[5.page_two.dart](#5-page_two.dart)
[6.id_page.dart](#6-id_page.dart)
[7.さいごに](#7-さいごに)

# 1. はじめに
routemasterはFlutterのNavigator2.0をラッピングしたライブラリで以下の特徴があります。
引用：https://qiita.com/tkou15/items/149036994257ae9a5b72
- URLとページのマッピングをシンプルに定義できる
- 使いやすくシンプルなAPI（例：routemaster.push('/page')
- ネストされたタブにも、非常に簡単なやり方で対応できる
- 複数のルートマッピングを定義できる (ログイン済みとログアウト済みのユーザを分けたり
- Observerを設定し、ルートの変化を簡単に聞き取ることができる
- 160個以上の Unit/Widget/Integrationテストで動作検証済み
<br>

今回は5つのページを使って説明します。
ページの概要は以下の通りです。

1. pubspec.yaml：pakageのインポート
1. main.dart：パスの設定、値を渡す
1. page_one.dart：page_two.dartにページ遷移
1. page_two.dart：page_one.dartからページ遷移
1. id_page.dart：値を受け取る


# 2. pubspec.yaml
- 公式からパッケージをインストールします。
pub.dev:routemaster1.0.1
https://pub.dev/packages/routemaster
<br>

- pubspec.yamlのdependenciesにパッケージを追加
routemaster: ^1.0.1
```
dependencies:
  flutter:
    sdk: flutter

  cupertino_icons: ^1.0.2
  routemaster: ^1.0.1
```
<br>

- flutter pub getを実行


# 3. main.dart
パス(URL)の設定をしていきましょう！
データや値を渡したいときも、このページで設定していきます。
```dart:main.dart
import 'package:flutter/material.dart';
import 'package:route_master2/id_page.dart';
import 'package:route_master2/page_one.dart';
import 'package:route_master2/page_two.dart';
import 'package:routemaster/routemaster.dart';

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

String id = "データを渡します！！！！！！"; //渡したいデータ

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp.router(
      routerDelegate: RoutemasterDelegate(
        routesBuilder: (context) => RouteMap(routes: {
          "/": (routeData) =>
              const MaterialPage(child: PageOne()), //page_one.dartのページにいく
          "/two": (routeData) =>
              const MaterialPage(child: PageTwo()), //page_two.dartのページにいく
          "/idPage": (route) => MaterialPage(
                child: IdPage(
                    id: id), //id_page.dartにString型の"id"という変数の箱を準備して、11行目のデータを渡す
              ),
        }),
      ),
      routeInformationParser: const RoutemasterParser(),
      title: 'Flutter Demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
    );
  }
}

```
MaterialAppをMaterial.routerにして以下を入れる
routerDelegate：Router とアプリとの相互作用のための中心的な役割を担うクラス
routesBuilder：ルート定義のためのビルディングブロック
RouteMap：パスのルート

# 4. page_one.dart
ElevatedButtonを使って、ページ遷移を実装していきます。
push時：Routemaster.of(context).push("main.dartで設定したパス")
pop時：Routemaster.of(context).pop

```dart:page_one.dart
import 'package:flutter/material.dart';
import 'package:routemaster/routemaster.dart';

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("PageOne"),
      ),
      body: Row(
        children: [
          ElevatedButton(
              onPressed: () {
                Routemaster.of(context).pop(); //1つ前のページに戻る
              },
              child: const Text("back")),
          ElevatedButton(
              onPressed: () {
                Routemaster.of(context).push("/two"); // "/two"のページに行く
              },
              child: const Text("next")),
        ],
      ),
    );
  }
}

```
# 5. page_two.dart
page_one.dartからページ遷移してきたページになります。
また、id_page.dartに遷移します。

```dart:page_two.dart
import 'package:flutter/material.dart';
import 'package:routemaster/routemaster.dart';

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: const Text("PageTwo"),
        ),
        body: Row(children: [
          ElevatedButton(
              onPressed: () {
                Routemaster.of(context).pop();
              },
              child: const Text("back")),
          ElevatedButton(
            onPressed: () {
              Routemaster.of(context).push("/idPage");
            },
            child: const Text("next"),
          ),
        ]));
  }
}

```
# 6. id_page.dart
ここでは、main.dartで渡した値を受け取るページになります。

```dart:id_page.dart
import 'package:flutter/material.dart';

class IdPage extends StatelessWidget {
  const IdPage({super.key, required this.id}); //インスタンス変数の定義

  final String id;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(id), //受け取ったデータを表示
      ),
    );
  }
}


```
# 7.さいごに
ここまで読んでいただきありがとうございました！
routemasterで簡単にURLをつけることができます。
ルーティング対応で、他にも試してほしいパッケージがございましたらコメントください:grin: