ルーター
ルートの定義
まず最初に、Framework7アプリを起動する際に、routes
という配列パラメータを使って、デフォルトのルートを渡します。
var app = new Framework7({
routes: [
{
name: 'about',
path: '/about/',
url: './pages/about.html',
},
{
name: 'news',
path: '/news/',
url: './pages/news.html',
options: {
animate: false,
},
},
{
name: 'users',
path: '/users/',
componentUrl: './pages/users.html',
options: {
props: {
users: ['John Doe', 'Vladimir Kharlampidi', 'Timo Ernst'],
},
},
on: {
pageAfterIn: function test (e, page) {
// ページがビューに入った後に何かをする
},
pageInit: function (e, page) {
// ページが初期化されたときに何かをする
},
}
},
// すべてのページにマッチするデフォルトルート (例: 404ページ)
{
path: '(.*)',
url: './pages/404.html',
},
],
});
アプリの初期化時に定義されたルートは、デフォルトルートであり、アプリ内のどのView/Routerでも利用することができます。
マルチビュー/ルーターアプリで、あるビュー/ルーターに独自の厳密なルートを持たせ、このビューではデフォルトルートを利用できないようにしたい場合は、ビューの初期化で同じroutes
パラメータを指定することができます。
var view1 = app.views.create('.view-1', {
routes: [
{
path: '/users/',
url: './pages/users.html',
},
{
path: '/user/',
url: './pages/user.html',
},
],
});
マルチビュー/ルーターアプリで、あるビュー/ルーターに追加ルートを持たせ、これらの追加ルートを他のビューでは利用できないようにしたい場合は、ビューのinitにroutesAdd
パラメータを指定することができます。
// このビューは、すべてのグローバルルートと独自の追加ルートをサポートします。
var view2 = app.views.create('.view-2', {
// これらのルートは、このビューでのみ利用可能です
routesAdd: [
{
path: '/blog/',
url: './pages/blog.html',
},
{
path: '/post/',
url: './pages/post.html',
},
],
})
ルートのプロパティ
それでは、各ルートのプロパティの意味を説明します。
Parameter | Type | Description | |
---|---|---|---|
name | string | ルートの名前、例:home (ホーム) | |
path | string | ルートのパス。このパスに一致するリンクをクリックすると、このルートが読み込まれることを意味します。または、APIを使用してこのパスで読み込むことができます。 | |
options | object | 追加のルートオプションを持つオブジェクト(オプション) | |
routes | array | ネストしたルートを持つ配列 | |
viewName | string | このルートが強制的にロードされるビュー名 | |
Master Detail | |||
master | boolean function(app, router) | このルートをマスタールートとして有効にします。これは、app とルーターのインスタンスを受け取るメソッドにすることもできます。このメソッドでは、true またはfalse を返す必要があります。
| |
detailRoutes | array | 詳細なルートを含む配列 | |
Lazy Modules | |||
modules | array | ルートをロードする前にロードする遅延モジュールを含む配列 | |
Content Related Properties The following route properties define how (from where/what) content should be loaded | |||
el | HTMLElement | 渡された HTMLElement によって DOM からページを読み込みます。ビューで stackPages が有効な場合にのみ使用できます。 | |
pageName | string | 同じ data-name 属性を持つページを DOM から読み込みます。ビューで stackPages が有効になっている場合にのみ使用できます。 | |
content | string | 指定されたコンテンツ文字列から動的なページを作成します。 | |
url | string | ページのコンテンツをAjaxで読み込みます。 また、ルートパスから
| |
component | object | 渡されたFramework7のルーターコンポーネントからページを読み込む | |
componentUrl | string | Ajaxでコンポーネントとしてページを読み込む また、ルートパスから | |
async | function(context) | 必要な非同期の操作を行い、必要なルートのコンテンツやオプションを返します。引数として、route callback contextオブジェクトを受け取ります。 | |
asyncComponent | function() | このメソッドは、Componentで解決されたPromiseか、Componentを含む このメソッドは、コンポーネントを動的にインポートするための、
| |
Routable Tabs | |||
tabs | array | タブルートを持つ配列 | |
Routable Modals | |||
actions | object | アクションシートルート | |
popup | object | ポップアップのルート | |
loginScreen | object | ログイン画面ルート | |
popover | object | ポップオーバールート | |
sheet | object | シートルート | |
Routable Panels | |||
panel | object | パネルルート | |
Events | |||
on | object | イベントハンドラーを持つオブジェクト | |
Alias & Redirect | |||
alias | string array | ルートのエイリアス、またはルートのエイリアスを持つ配列です。ここでは、エイリアス パス を指定する必要があります。 | |
redirect | string function(context) | ルートのリダイレクト。パスではなく、リダイレクト先の url を指定する必要があります。If メソッドの引数として、ルートコールバックコンテキストオブジェクトを受け取ります。 | |
Before Enter/Leave | |||
beforeEnter | function(context) array | ルートのロード/エントリーの前に実行される関数(または関数の配列)です。ルートのロードを実行するには、 resolve を呼び出す必要があります。配列`の場合、処理を進めるためには、配列内のすべての関数を解決する必要があります。メソッドの場合は、引数としてルートコールバックコンテキストオブジェクトを受け取ります。 | |
beforeLeave | function(context) array | ルートのアンロード/離脱の前に実行される関数(または関数の配列)です。ナビゲーションを実行するには、 resolve を呼び出す必要があります。配列`の場合、処理を進めるためには、配列内のすべての関数を解決しなければなりません。メソッドの場合は、引数としてルートコールバックコンテキストオブジェクトを受け取ります。 | |
keepAlive | |||
keepAlive | boolean | いわゆる keepAlive ルートを有効にします。有効にすると、一度読み込まれたページとそのコンポーネント(Vue、React、Routerコンポーネント)は、決して破壊されません。その代わり、DOMから切り離され、必要に応じて再利用されます。 |
以下は、可能なオプションのほとんどの例です。
routes: [
// Ajaxによる読み込み
{
path: '/about/',
url: './pages/about.html',
},
// コンテンツからの動的ページ
{
path: '/news/',
content: `
<div class="page">
<div class="page-content">
<div class="block">
<p>This page created dynamically</p>
</div>
</div>
</div>
`,
},
// DOMに表示されたページ名(data-name="services")による読み込み
{
path: '/services/',
pageName: 'services',
},
// ページのHTML要素から
{
path: '/contacts/',
el: document.querySelector('.page[data-name="contacts"]'),
},
// コンポーネントから
{
path: '/posts/',
component: {
// 以下を見る
},
},
// コンポーネントのURL
{
path: '/post/:id/',
componentUrl: './pages/component.html',
},
// 非同期
{
path: '/something/',
async: function ({ app, to, resolve }) {
// リクエストされたルート
console.log(to);
// 外部データを取得してページ内容を返す
app.request.json('http://some-endpoint/').then(function (res) {
resolve(
// 何をどのように読み込むか
{
content: `<div class="page">${res.data.users}</div>`
},
);
});
}
}
],
ルートのパス
前述したように、ルートの path
プロパティは、次のルートがapiまたは同じパスのリンクをクリックして読み込まれたときに、ブラウザウィンドウのアドレスバーに表示されるパス/URLを意味します(browserHistory
が有効な場合)。
また、ダイナミックパスもサポートしています。例えば、/blog/users/:userId/posts/:postId/
というパスがルートにあり、/blog/users/12/posts/25
というhrefを持つリンクをクリックすると、読み込まれたページでは、{ userId.12, postId.25
を含むroute.params
オブジェクトにアクセスします。12, postId: 25 }`
ルートのパスマッチングは、Path To Regexpライブラリで処理されているので、そこでサポートされているものはすべてFramework7でもサポートされています。例えば、全てのパスにマッチするデフォルトのルートを追加したい場合、次のような正規表現を使うことができます。
// デフォルトルート、すべてのページにマッチ(例:404ページ
{
path: '(.*)',
url: './pages/404.html',
},
ルートオプション
options`プロパティに渡すことができる、追加のルートオプションを見てみましょう。
Parameter | Type | Description |
---|---|---|
animate | boolean | ページをアニメーションにするかどうか (ルーターのデフォルト設定を上書きします) |
history | boolean | ルーターの履歴にページを保存するかどうか |
browserHistory | boolean | ブラウザの状態でページを保存するかどうか。browserHistory を使用している場合は、ここで false` を渡すことで、ブラウザの履歴にルートが残らないようにすることができます。 |
reloadCurrent | boolean | 現在のページをルートの新しいページに置き換えます。この場合、アニメーションは行いません。 |
reloadPrevious | boolean | 履歴の前のページをルートの新しいページで置き換えます。 |
reloadAll | boolean | 新しいページをロードし、履歴とDOMから前のページをすべて削除します。 |
clearPreviousHistory | boolean | 前のページの履歴は、指定されたルートにリロード/ナビゲートした後にクリアされます。 |
ignoreCache | boolean | true`に設定すると、キャッシュにそのようなURLがあっても無視して、XHRを使って再読み込みします。 |
force | boolean | true`に設定すると、履歴の前のページを無視して、指定したページを読み込みます。 |
props | object | Vue/Reactのページコンポーネントのプロップとして渡されるプロップ |
transition | string | カスタムページトランジション名 |
openIn | string | ページルートをモーダルまたはパネルとして開くことができます。つまり、以下のいずれかになります。popup, popover, loginScreen, sheet, panel`. |
ルートコールバックのコンテキスト
async,
redirect,
beforeEnter,
beforeLeave` のルートプロパティで使用される、ルートコンテキストのコールバックのフォーマットです。
Properties | |
---|---|
app | グローバルアプリのインスタンスへのリンク |
to | リクエストされたルート |
from | 現在アクティブなルート |
router | 現在のルーターインスタンス |
resolve | ルーティングを解決/進展させるために呼び出すメソッド |
reject | ルーティングを防ぐ/拒否するために呼び出す方法 |
direction | ナビゲーションの方向、forward またはbackward が可能 |
非同期ルート
async
ルートプロパティは、動的なルートプロパティを返すために設計された、非常に強力なツールです。これは次のような引数を持つ関数です。
async(context)
- context - ルートコールバックのコンテキスト。
ルートコールバックのresolve
メソッドは、以下のようなフォーマットになっています。
resolve(parameters, options)
- parameters object - 解決されたルートのコンテンツを持つオブジェクト。url
、
content、
component、
componentUrl`のいずれかのプロパティを含む必要があります。 - options object - Route Optionsを持つオブジェクト。
reject
コールバック関数は、引数を持ちません。
reject()
非同期メソッドで resolve
や reject
を呼び出すまでは、ルーティングはブロックされることに注意してください。
例:
routes = [
{
path: '/foo/',
async({ resolve, reject }) {
if (userIsLoggedIn) {
resolve({ url: 'secured.html' })
} else {
resolve({ url: 'login.html' })
}
}
}
]
イベントのルーティング
on` ルートプロパティを使って、このページのルート内にすべてのページイベントを追加することができます。例えば、以下のようになります。
var app = new Framework7({
routes: [
// ...
{
path: '/users/',
url: './pages/users.html',
on: {
pageBeforeIn: function (event, page) {
// ページがビューに入る前に何かをする
},
pageAfterIn: function (event, page) {
// ページがビューに入った後に何かをする
},
pageInit: function (event, page) {
// ページが初期化されたときに何かをする
},
pageBeforeRemove: function (event, page) {
// ページがDOMから削除される前に何かをする
},
}
},
// ...
],
});
このようなルートイベントは、実際にはDOMイベントであることに注意してください。そのため、このようなイベントハンドラは、第1引数にイベントそのものを含むevent
を、第2引数にページデータを含むpage
を受け取ります。
また、このようなイベントハンドラのコンテキスト (this
) は、関連する Router インスタンスを指します。
ルートの入れ子
ルートを入れ子にすることも可能です(ルートの中のルート)。
routes = [
{
path: '/faq/',
url: './pages/faq.html',
},
{
path: '/catalog/',
url: './pages/catalog.html',
routes: [
{
path: 'computers/',
url: './pages/computers.html',
},
{
path: 'monitors/',
url: './pages/monitors.html',
},
...
],
}
];
これはどういうことでしょうか?理解を深めるために、実際には(フードの下では)そのようなルートは次のルートにマージされます。
routes = [
{
path: '/faq/',
url: './pages/faq.html',
},
{
path: '/catalog/',
url: './pages/catalog.html',
}
{
path: '/catalog/computers/',
url: './pages/computers.html',
},
{
path: '/catalog/monitors/',
url: './pages/monitors.html',
},
];
例えば、/catalog/
のページに以下のようなリンクがあるとします。
<a href="computers/">Computers</a>
- 期待通りに動作します。リンクは現在のルート(/catalog/
+computers/
)にマージされて、ルートにある/catalog/computers/
になります。<a href="./computers/">Computers</a>
- パスの最初の./
は同じサブレベルを意味するので、ケース1と同じように動作します。<a href="/catalog/computers/">Computers</a>
- パスの最初の/
(スラッシュ) がルートを意味するので、ケース 1 と同じように期待通りに動作します。そして、マージされたルートにはそのようなルートがあります。<a href="/computers/">Computers</a>
- 期待通りには動作しません なぜなら、先頭の/
(スラッシュ)はルートを意味するからです。そして、私たちのルートには、そのような/computers/
ルートのルートはありません。
詳細ルート
マスターの詳細表示では、マスタールートに master: true
に加えて、detailRoutes
を指定することもできます。
detailRoutes`が指定されると、詳細ルートに移動する際に、そのマスタールートもプリロードされます。
しかし、ネストされたルート(routes
パラメータで指定)とは異なり、詳細ルートの path
はマスタールートの path
にマージされません。
routes = [
{
path: '/blog/',
url: './news.html',
master: true,
detailRoutes: [
{
/* We need to specify detail route path from root */
path: '/blog/:postId/',
url: './post.html',
},
],
},
// ...
]
ルーティング可能なタブ
ルーティング可能なタブとは何を意味し、なぜそれが良いのでしょうか?
- まず第一に、いわゆる特別なタブリンクではなく、通常のリンクでタブに移動する機会を提供します。
- 第二に、そのようなルートに移動すると、必要なタブを開いたままページを読み込むことができます。
- 第三に、ブラウザの履歴を有効にすると、履歴をさかのぼったり、進んだりしたときに、同じタブが開かれます。
- 最後に、ルーティング可能なタブを使用する場合、ページと同じ方法でタブのコンテンツを読み込むことができます。
まず最初に、アプリのルートでタブのルートを指定する必要があります。例えば、/tabs/ ルートにルーティング可能なタブを持つページがあるとします。
routes = [
{
path: '/about-me/',
url: './pages/about-me/index.html',
// tabs "プロパティをルートに渡す
tabs: [
// 最初の (デフォルトの) タブは、ページ自体と同じ URL を持ちます。
{
path: '/',
id: 'about',
// このタブのコンテンツを content string から読み込む
content: `
<div class="block">
<h3>About Me</h3>
<p>...</p>
</div>
`
},
// 2つ目のタブ
{
path: '/contacts/',
id: 'contacts',
// このタブのコンテンツをAjaxリクエストで読み込む
url: './pages/about-me/contacts.html',
},
// 3つ目のタブ
{
path: '/cv/',
id: 'cv',
// このタブのコンテンツをAjaxリクエストでコンポーネントとして読み込む
componentUrl: './pages/about-me/cv.html',
},
],
}
]
例えば、/about-me/
のページでは、次のような構造になっていると思います。
<div class="page">
<div class="navbar">
<div class="navbar-bg"></div>
<div class="navbar-inner">
<div class="title">About Me</div>
</div>
</div>
<div class="toolbar tabbar toolbar-bottom">
<div class="toolbar-inner">
<a href="./" class="tab-link" data-route-tab-id="about">About</a>
<a href="./contacts/" class="tab-link" data-route-tab-id="contacts">>Contacts</a>
<a href="./cv/" class="tab-link" data-route-tab-id="cv">>CV</a>
</div>
</div>
<div class="tabs tabs-routable">
<div class="tab page-content" id="about"></div>
<div class="tab page-content" id="contacts"></div>
<div class="tab page-content" id="cv"></div>
</div>
</div>
通常の Tabs とほぼ同じですが、タブリンクやタブに tab-link-active
や tab-active
といったクラスが存在しないという違いがあります。これらのクラスとタブは、ルータによって切り替えられます。また、新たに data-route-tab-id
属性が追加されました。これは、タブスイッチャーが、どのリンクが選択されたルートに関連しているかを理解するために必要です。
ルーティング可能なタブとその追加イベントについては、Tabsコンポーネントページの適切なセクションで詳しく説明されています。
ルーティング可能なモーダル
モーダルもルーティング可能です。ここでいうモーダルとは、以下のコンポーネントを指します。Popup、Popover、Actions Sheet、Login Screen、Sheet Modalです。ここではPopupとLogin Screenの方が使用例が多いでしょう。
また、ルーティング可能なタブやページと同じ機能を備えています。
- いわゆる特別なリンクやAPIではなく、通常のリンクでモーダルを開くことができます。
- ブラウザの履歴を有効にすると、ブラウザを更新したり、履歴をさかのぼったりしたときに、同じモーダルが開かれます。
- ルーティング可能なモーダルでは、ページと同じように、
url
、content
、component
、componentUrl
を使用して、モーダル自体やそのコンテンツをロードすることができます。
routes = [
...
// 渡されたHTML文字列からポップアップを作成する
{
path: '/popup-content/',
popup: {
content: `
<div class="popup">
<div class="view">
<div class="page">
...
</div>
</div>
</div>
`
}
},
// ファイルからAjaxでログイン画面を読み込む
{
path: '/login-screen-ajax/',
loginScreen: {
url: './login-screen.html',
/* login-screen.html contains:
<div class="login-screen">
<div class="view">
<div class="page">
...
</div>
</div>
</div>
*/
},
},
// コンポーネントファイルからポップアップを読み込む
{
path: '/popup-component/',
loginScreen: {
componentUrl: './popup-component.html',
/* popup-component.html contains:
<template>
<div class="popup-screen">
<div class="view">
<div class="page">
...
</div>
</div>
</div>
</template>
<style>...</style>
<script>...</script>
*/
},
},
// 非同期ルートを使って、ユーザーがログインしているかどうかをチェックします。
{
path: '/secured-content/',
async({ resolve }) {
if (userIsLoggedIn) {
resolve({
url: 'secured-page.html',
});
} else {
resolve({
loginScreen: {
url: 'login-screen.html'
} ,
});
}
},
}
]
上記の例では
- href属性が
/popup-content/
のリンクをクリックすると、指定した文字列の内容からポップアップを開きます。 - /login-screen-ajax/
href属性のリンクをクリックすると、
login-screen.html`ファイルにAjaxリクエストを行い、ログイン画面として開きます。 - popup-component/
href 属性を持つリンクをクリックすると、
popup-component.html` ファイルへのAjaxリクエストが実行され、Router Componentとして解析され、ポップアップとして開かれます。 - また、
/secured-content/
href 属性を持つリンクをクリックすると、ユーザーがログインしている場合はsecured-page.html
からページをロードし、ユーザーがログインしていない場合はlogin-screen.html
ファイルからログイン画面を開きます。
ルーティング可能なパネル
Framework7のバージョン3.2.0からルーティング可能なパネルが利用できるようになりました。
パネル(サイドパネル)もルーティング可能で、ルーティング可能なモーダルやページと同様の機能を備えています。
- いわゆる特別なリンクやAPIではなく、通常のリンクでパネルを開くことができます。
- ブラウザの履歴を有効にすると、ブラウザを更新したり、履歴をさかのぼったり進んだりしたときに、同じパネルが開かれます。
- ルーティング可能なパネルでは、ページやモーダルと同じ方法、つまり、
url
、content
、component
、componentUrl
を使用して、パネル自体やそのコンテンツをロードすることができます。
routes = [
...
// 渡された HTML 文字列から Panel を作成します。
{
path: '/left-panel/',
panel: {
content: `
<div class="panel panel-left panel-cover">
<div class="view">
<div class="page">
...
</div>
</div>
</div>
`
}
},
// Ajax によるファイルからの Panel の読み込み
{
path: '/right-panel-ajax/',
panel: {
url: './right-panel.html',
/* right-panel.html contains:
<div class="panel panel-right panel-reveal">
<div class="view">
<div class="page">
...
</div>
</div>
</div>
*/
},
},
// コンポーネントファイルからパネルを読み込む
{
path: '/panel-component/',
panel: {
componentUrl: './panel-component.html',
/* panel-component.html contains:
<template>
<div class="panel panel-left panel-cover">
<div class="view">
<div class="page">
...
</div>
</div>
</div>
</template>
<style>...</style>
<script>...</script>
*/
},
},
]
上記の例によると
- href 属性が
/left-panel/
のリンクをクリックすると、指定した文字列のコンテンツからパネルが開かれます。 - right-panel-ajax/
href 属性を持つリンクをクリックすると、
right-panel.html` ファイルへの Ajax リクエストが実行され、右パネルとして開かれます。 - また、
/panel-component/
href 属性を持つリンクをクリックすると、panel-component.html
ファイルへの Ajax リクエストが実行され、それが Router Component として解析され、Panel として開かれます。
なお、ルーティング可能なパネルは、静的なパネルと混在させることはできません。ルーティング可能なパネルは、静的なパネルと混在させることはできませんので、アプリ内に静的な左パネルがある場合は、右パネルのみをルーティング可能なパネルとして読み込むことができます。
入室前/退室前のルーティング
beforeEnter
とbeforeLeave
のルートフックは、ルートのロード(enter)とアンロード(leave)の前に、追加のチェックや追加のアクションの実行、何かのロード/送信を行う必要がある場合に、非常に便利です。フックは単一のメソッドでも、実行されるメソッドの配列でも構いません。例えば、以下のようになります。
routes = [
{
path: 'profile',
url: 'profile.html',
beforeEnter: function ({ resolve, reject }) {
if (/* some condition to check user is logged in */) {
resolve();
} else {
// 認証されていないユーザーにはこのページへのアクセスを許可しない
reject();
}
},
},
{
path: 'profile-edit',
url: 'profile-edit.html',
beforeLeave: function ({ resolve, reject }) {
if (/* user didn't save edited form */) {
app.dialog.confirm(
'Are you sure you want to leave this page without saving data?',
function () {
// ナビゲーションを進める
resolve();
},
function () {
// ページに留まる
reject();
}
)
} else {
resolve();
}
}
}
]
もちろん、関数の配列として渡された場合には、複数のフックがサポートされています。
function checkAuth({ to, from, resolve, reject }) {
if (/* some condition to check user is logged in */) {
resolve();
} else {
reject();
}
}
function checkPermission({ to, from, resolve, reject }) {
if (/* some condition to check user edit permission */) {
resolve();
} else {
reject();
}
}
routes = [
{
path: '/profile/',
url: 'profile.html',
// ユーザーがログインしているかどうかの確認
beforeEnter: checkAuth,
},
{
path: '/profile-edit/',
url: 'profile-edit.html',
// ユーザーがログインしていて、必要なパーミッションを持っているかどうかのチェック
beforeEnter: [checkAuth, checkPermission],
}
]
リダイレクトとエイリアス
エイリアス
ルートのエイリアスは、ルートの alias
プロパティを使って渡すことができます。この場合のエイリアスとは、基本的に同じルートが複数のパスでアクセスできることを意味します。
routes = [
{
path: '/foo/',
url: 'somepage.html',
alias: '/bar/',
},
{
path: '/foo2/',
url: 'anotherpage.html',
alias: ['/bar2/', '/baz/', '/baz2/'],
}
]
上の例によると
- foo/
または
/bar/の URL でページをリクエストすると、最初のルートがマッチし、
somepage.html` からページが読み込まれます。 - foo2/
,
/bar2/,
/baz/,
/baz2/のURLでページをリクエストすると、2番目のルートがマッチして、
anotherpage.html` からページが読み込まれます。
リダイレクト
redirect`プロパティを使って、ルートのリダイレクトを渡すことができます。
- もし
redirect
を文字列
として渡した場合、ここに直接のリダイレクト URL を渡さなければなりません。 - 関数
として
redirect`を渡した場合、リダイレクトURLを関数のresolveパラメータで呼び出す必要があります。
例:
routes = [
{
path: '/foo/',
url: 'somepage.html',
},
{
path: '/bar/',
redirect: '/foo/',
},
{
path: '/baz/',
redirect: function ({to, resolve, reject}) {
// user "というクエリパラメータがある場合
if (to.query.user) {
// そのURLにリダイレクトする
resolve('/foo/?user=' + to.query.user);
}
// そうでなければ何もしない
else reject();
}
}
]
上記の例は次のような意味です。
- bar/
の URL をリクエストすると、ルーターは
/foo/の URL にリダイレクトし、この新しい URL にマッチするルートを検索します。この場合、パス
/foo/を持つ最初のルートにマッチし、
somepage.html` からページをロードします。 - /baz/?user=john
をリクエストすると、最初のルートにマッチするURL
/foo/?user=john`にリダイレクトされます。 - (クエリなしで)
/baz/
をリクエストすると、何も起こりません。
リダイレクトの際には、エイリアスのようにルートのパスではなく、URLを渡すことに注意してください。
キープアライブ
keepAliveルートは、Framework7のバージョン3.6.0から利用可能です。
keepAlive`を有効にすると、ルーターがそのようなページを読み込んだときに、そのページと、必要に応じてそのコンポーネント(Vue、React、またはRouterコンポーネント)は、決して破壊されません。代わりに、DOMから切り離され、必要に応じて再利用されます。
これは、あまり頻繁に更新されない「重い」ページで有効にすると便利です。例えば、地図を含むページや、重いキャンバスやその他の計算を行うページなどです。通常のロジックでは、これらの重い計算は、このページが訪問されるたびに行われます。しかし、keepAliveでは、それは一度だけ行われ、次回の訪問時には、ルータはすでにレンダリングされたページのDOM要素を再利用します。
また、ページの状態を本当に保存する必要がある場合にも便利です。keepAliveを有効にすると、次にページが読み込まれたときに、すべてのDOM変更とフォーム要素の状態が保存されます。
しかし、注意すべき点もあります。
- これは
async
ルートではサポートされていません。 - ページでのみサポートされています(パネルやモーダルではサポートされていません)。
- 動的なルートパスを持っていたり(
/some-page/:foo/:bar
)、ページルートのクエリに依存している場合(?foo=bar
)は、最初にロードされた後は、クエリとルートのパラメータは変更されません。 page:beforeremove
,pageBeforeRemove
ページイベントは、そのようなページでは決して発生しません。- Vue コンポーネントとして使用している場合、
beforeDestroy
,destroyed
フックは、そのようなコンポーネントでは決して発生しません。また、created
,mounted
フックは一度だけ実行されます。 - これをReactコンポーネントとして使用する場合、
componentWillUnmount
メソッドはこのようなコンポーネントに対しては決して発生しません。componentWillMount,
componentDidMount` メソッドは一度だけ実行されます。 - F7のRouterコンポーネントとして使用した場合、
beforeDestroy
,destroyed
フックは、そのようなコンポーネントに対しては決して発生しません。また、created
,mounted
フックは一度だけ実行されます。
コンポーネントやページのライフサイクルの落とし穴を避けるために、以下のページイベントに依存することをお勧めします。
page:mounted
- keepAlive ルートページの DOM 要素が取り付けられたり、再び取り付けられたりしたときに、常に呼び出されます。page:beforeunmount
- keepAliveルートのページで、そのDOM要素がDOMから切り離されるときに、常に呼び出されます。
keepAliveルートを作成するには、パラメータに keepAlive: true
を渡すだけです。
import SomPageComponent from './some-page.js';
var routes = [
/* Usual route */
{
path: '/',
url: './pages/home.html',
},
/* Alive route. Will be loaded from file first time, and then will reuse rendered DOM element */
{
path: '/map/',
url: './pages/map.html',
keepAlive: true,
},
/* Alive route. Will be created as component, and then will reuse rendered DOM element */
{
path: '/some-page/',
component: SomPageComponent,
keepAlive: true,
},
];