スポンサー
Support Framework7

ルーター

    ルートの定義

    まず最初に、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',
        },
      ],
    })

    ルートのプロパティ

    それでは、各ルートのプロパティの意味を説明します。

    ParameterTypeDescription
    namestringルートの名前、例:home(ホーム)
    pathstringルートのパス。このパスに一致するリンクをクリックすると、このルートが読み込まれることを意味します。または、APIを使用してこのパスで読み込むことができます。
    optionsobject追加のルートオプションを持つオブジェクト(オプション)
    routesarrayネストしたルートを持つ配列
    viewNamestringこのルートが強制的にロードされるビュー名
    Master Detail
    masterboolean
    function(app, router)
    このルートをマスタールートとして有効にします。これは、appとルーターのインスタンスを受け取るメソッドにすることもできます。このメソッドでは、trueまたはfalseを返す必要があります。
    {
      url: '/some-page/',
      master(app) {
        if (app.device.desktop) return true;
        return false;
      }
    }
    detailRoutesarray詳細なルートを含む配列
    Lazy Modules
    modulesarrayルートをロードする前にロードする遅延モジュールを含む配列
    Content Related Properties
    The following route properties define how (from where/what) content should be loaded
    elHTMLElement渡された HTMLElement によって DOM からページを読み込みます。ビューで stackPages が有効な場合にのみ使用できます。
    pageNamestring同じ data-name 属性を持つページを DOM から読み込みます。ビューで stackPages が有効になっている場合にのみ使用できます。
    contentstring指定されたコンテンツ文字列から動的なページを作成します。
    urlstringページのコンテンツをAjaxで読み込みます。

    また、ルートパスから {{paramName}} 式を使った動的なルートパラメータもサポートしています。

    {
      path: '/users/:userId/posts/:postId',
      url: 'http://myapp.com/posts/{{userId}}/{{postId}}'
    }
    componentobject渡されたFramework7のルーターコンポーネントからページを読み込む
    componentUrlstringAjaxでコンポーネントとしてページを読み込む

    また、ルートパスから {paramName}} 式を使った動的なルートパラメータもサポートしています。

    asyncfunction(context)必要な非同期の操作を行い、必要なルートのコンテンツやオプションを返します。引数として、route callback contextオブジェクトを受け取ります。
    asyncComponentfunction()

    このメソッドは、Componentで解決されたPromiseか、Componentを含む.defaultプロパティを持つESモジュールを返す必要があります。

    このメソッドは、コンポーネントを動的にインポートするための、asyncの短縮版として設計されています。例えば、以下のようになります。

    {
      path: '/some-page/',
      asyncComponent: () => import('./path/to/some-page.js'),
    }
    Routable Tabs
    tabsarrayタブルートを持つ配列
    Routable Modals
    actionsobjectアクションシートルート
    popupobjectポップアップのルート
    loginScreenobjectログイン画面ルート
    popoverobjectポップオーバールート
    sheetobjectシートルート
    Routable Panels
    panelobjectパネルルート
    Events
    onobjectイベントハンドラーを持つオブジェクト
    Alias & Redirect
    aliasstring
    array
    ルートのエイリアス、またはルートのエイリアスを持つ配列です。ここでは、エイリアス パス を指定する必要があります。
    redirectstring
    function(context)
    ルートのリダイレクト。パスではなく、リダイレクト先の url を指定する必要があります。If メソッドの引数として、ルートコールバックコンテキストオブジェクトを受け取ります。
    Before Enter/Leave
    beforeEnterfunction(context)

    array
    ルートのロード/エントリーの前に実行される関数(または関数の配列)です。ルートのロードを実行するには、 resolve を呼び出す必要があります。配列`の場合、処理を進めるためには、配列内のすべての関数を解決する必要があります。メソッドの場合は、引数としてルートコールバックコンテキストオブジェクトを受け取ります。
    beforeLeavefunction(context)

    array
    ルートのアンロード/離脱の前に実行される関数(または関数の配列)です。ナビゲーションを実行するには、 resolve を呼び出す必要があります。配列`の場合、処理を進めるためには、配列内のすべての関数を解決しなければなりません。メソッドの場合は、引数としてルートコールバックコンテキストオブジェクトを受け取ります。
    keepAlive
    keepAlivebooleanいわゆる 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`プロパティに渡すことができる、追加のルートオプションを見てみましょう。

    ParameterTypeDescription
    animatebooleanページをアニメーションにするかどうか (ルーターのデフォルト設定を上書きします)
    historybooleanルーターの履歴にページを保存するかどうか
    browserHistorybooleanブラウザの状態でページを保存するかどうか。browserHistory を使用している場合は、ここで false` を渡すことで、ブラウザの履歴にルートが残らないようにすることができます。
    reloadCurrentboolean現在のページをルートの新しいページに置き換えます。この場合、アニメーションは行いません。
    reloadPreviousboolean履歴の前のページをルートの新しいページで置き換えます。
    reloadAllboolean新しいページをロードし、履歴とDOMから前のページをすべて削除します。
    clearPreviousHistoryboolean前のページの履歴は、指定されたルートにリロード/ナビゲートした後にクリアされます。
    ignoreCachebooleantrue`に設定すると、キャッシュにそのようなURLがあっても無視して、XHRを使って再読み込みします。
    forcebooleantrue`に設定すると、履歴の前のページを無視して、指定したページを読み込みます。
    propsobjectVue/Reactのページコンポーネントのプロップとして渡されるプロップ
    transitionstringカスタムページトランジション名
    openInstringページルートをモーダルまたはパネルとして開くことができます。つまり、以下のいずれかになります。popup, popover, loginScreen, sheet, panel`.

    ルートコールバックのコンテキスト

    async, redirect, beforeEnter, beforeLeave` のルートプロパティで使用される、ルートコンテキストのコールバックのフォーマットです。

    Properties
    appグローバルアプリのインスタンスへのリンク
    toリクエストされたルート
    from現在アクティブなルート
    router現在のルーターインスタンス
    resolveルーティングを解決/進展させるために呼び出すメソッド
    rejectルーティングを防ぐ/拒否するために呼び出す方法
    directionナビゲーションの方向、forwardまたはbackwardが可能

    非同期ルート

    async ルートプロパティは、動的なルートプロパティを返すために設計された、非常に強力なツールです。これは次のような引数を持つ関数です。

    ルートコールバックのresolveメソッドは、以下のようなフォーマットになっています。

    resolve(parameters, options)

    • parameters object - 解決されたルートのコンテンツを持つオブジェクト。urlcontentcomponentcomponentUrl`のいずれかのプロパティを含む必要があります。
    • options object - Route Optionsを持つオブジェクト。

    reject コールバック関数は、引数を持ちません。

    reject()

    非同期メソッドで resolvereject を呼び出すまでは、ルーティングはブロックされることに注意してください。

    例:

    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/のページに以下のようなリンクがあるとします。

    1. <a href="computers/">Computers</a> - 期待通りに動作します。リンクは現在のルート(/catalog/ + computers/)にマージされて、ルートにある/catalog/computers/になります。

    2. <a href="./computers/">Computers</a> - パスの最初の ./ は同じサブレベルを意味するので、ケース1と同じように動作します。

    3. <a href="/catalog/computers/">Computers</a> - パスの最初の / (スラッシュ) がルートを意味するので、ケース 1 と同じように期待通りに動作します。そして、マージされたルートにはそのようなルートがあります。

    4. <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-activetab-active といったクラスが存在しないという違いがあります。これらのクラスとタブは、ルータによって切り替えられます。また、新たに data-route-tab-id 属性が追加されました。これは、タブスイッチャーが、どのリンクが選択されたルートに関連しているかを理解するために必要です。

    ルーティング可能なタブとその追加イベントについては、Tabsコンポーネントページの適切なセクションで詳しく説明されています。

    ルーティング可能なモーダル

    モーダルもルーティング可能です。ここでいうモーダルとは、以下のコンポーネントを指します。PopupPopoverActions SheetLogin ScreenSheet Modalです。ここではPopupとLogin Screenの方が使用例が多いでしょう。

    また、ルーティング可能なタブやページと同じ機能を備えています。

    • いわゆる特別なリンクやAPIではなく、通常のリンクでモーダルを開くことができます。
    • ブラウザの履歴を有効にすると、ブラウザを更新したり、履歴をさかのぼったりしたときに、同じモーダルが開かれます。
    • ルーティング可能なモーダルでは、ページと同じように、urlcontentcomponentcomponentUrlを使用して、モーダル自体やそのコンテンツをロードすることができます。
    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ではなく、通常のリンクでパネルを開くことができます。
    • ブラウザの履歴を有効にすると、ブラウザを更新したり、履歴をさかのぼったり進んだりしたときに、同じパネルが開かれます。
    • ルーティング可能なパネルでは、ページやモーダルと同じ方法、つまり、urlcontentcomponentcomponentUrlを使用して、パネル自体やそのコンテンツをロードすることができます。
    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 として開かれます。

    なお、ルーティング可能なパネルは、静的なパネルと混在させることはできませんルーティング可能なパネルは、静的なパネルと混在させることはできませんので、アプリ内に静的な左パネルがある場合は、右パネルのみをルーティング可能なパネルとして読み込むことができます。

    入室前/退室前のルーティング

    beforeEnterbeforeLeaveのルートフックは、ルートのロード(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,
      },
    ];