Router
シングルページアプリケーション(SPA)におけるルータは URL よってページを出し分けます。 リンクがクリックされたときに異なるリソースを要求するというデフォルトの動作の代わりに、ルータはアプリケーション内の有効なルートを指すように URL をローカルに設定します。 ルータはこの変更を検出してから、何をレンダリングするかを決定します。
コアとなる要素
Route
URL 内のドメインの後のすべてを表す文字列と、オプションで history API に保存されている状態を含みます。
RouteService
ブラウザとやりとりしてルーティングを決めます。
RouteAgent
RouteService を所有し、ルートが変更された際の更新を調整するために使用します。
Switch
Switch
トレイトはRoute
をトレイトの実装する側の間で変換するために用いられます。
Router
Router コンポーネントは RouteAgent とやり取りし、エージェントがどうスイッチするか Routes を自動的に解決します。 これは、結果として得られるスイッチがどのように Html に変換されるかを指定できるようにするため、props を介して公開されます。
ルータをどのように使うか
まず、アプリケーションのすべての状態を表す型を作成します。
これは通常は列挙型ですが、構造体もサポートされており、Switch
を実装した他のアイテムを内部に入れ子にすることができることに注意してください。
次に、Switch
を型に継承させなければいけません。
列挙型の場合は全ての variant は#[to = "/some/route"]
とアノテーションされている必要があり、代わり構造体を用いている場合は構造体宣言が外部から見えるようにしてなければいけません。
#[derive(Switch)]
enum AppRoute {
#[to="/login"]
Login,
#[to="/register"]
Register,
#[to="/delete_account"]
Delete,
#[to="/posts/{id}"]
ViewPost(i32),
#[to="/posts/view"]
ViewPosts,
#[to="/"]
Home
}
Switch
用の派生マクロによって生成された実装は、各 variant を最初から最後までの順にマッチさせようとするので、指定したto
アノテーションのうち 2 つのルートにマッチする可能性がある場合は、最初のルートがマッチし、2 つ目のルートは試行されないことに注意してください。例えば、以下のSwitch
を定義した場合、マッチするルートはAppRoute::Home
だけになります。
#[derive(Switch)]
enum AppRoute {
#[to="/"]
Home,
#[to="/login"]
Login,
#[to="/register"]
Register,
#[to="/delete_account"]
Delete,
#[to="/posts/{id}"]
ViewPost(i32),
#[to="/posts/view"]
ViewPosts,
}
また、#[to = ""]
アノテーションの中で{}
のバリエーションを使ってセクションをキャプチャすることもできます。
{}
は、次の区切り文字(コンテキストに応じて "/", "?", "&", "#" のいずれか) までのテキストをキャプチャします。
{*}
は、次の文字が一致するまでテキストをキャプチャすることを意味します。
{<number>}
は、指定した数の区切り文字が見つかるまでテキストをキャプチャすることを意味します
(例: {2}
は区切り文字が 2 つ見つかるまでキャプチャします)。
名前付きフィールドを持つ構造体や列挙型の場合は、キャプチャグループ内で以下のようにフィールドの名前を指定する必要があります。
{user_name}
または {*:age}
のように、キャプチャグループ内でフィールドの名前を指定しなければなりません。
Switch トレイトは文字列よりも構造化されたキャプチャグループで動作します。
Switch
を実装した任意の型を指定することができます。
そのため、キャプチャグループが usize
であることを指定することができ、URL のキャプチャ部分がそれに変換できない場合、variant はマッチしません。