owned mediaウェブ制作に役立つコンテンツを発信中!

Nuxt.js + TypeScriptでmiddlewareを使ってページ遷移時に処理を実行する

Nuxt.jsでページ遷移時に処理を行う時にはwatchオプションでルーティングの値の変更を監視することで実行していたのですが(参考記事「Vue.jsでwatchを使ってページ遷移やstateの値の更新を監視する」)TypeScriptを導入してからはなかなか上手くいかないことがあり、調べても情報が見つからなかったりと解決方法に困っていました。そこでそもそもwatchオプションではなく別の方法にするべきではということで、今回はmiddlewareを使ってページ遷移時の処理を作成してみたいと思います。   今回はTypeScriptで書いていく形になるので「@nuxt/types」のモジュールが必要になります。このモジュールがない場合にはあらかじめインストールしておきます。
$ yarn add @nuxt/types
  middlewareはNuxt.jsにおいてページ表示前に実行される処理を書くところで、storeの情報を扱ったり、リダイレクトを行ったりすることができます。これを使って、ページ遷移時に特定の処理を実行させることができます。使い方としては、ソースディレクトリ直下にある「middleware」ディレクトリ内にファイルを作成し、そこに下記のように処理を書いていきます。 【middleware/routing.ts】
import { Middleware } from '@nuxt/types'

const routing: Middleware = (context) => {
  console.log('ページ遷移されました')
}

export default routing
  そしてNuxt.jsの設定ファイルである「nuxt.config.js」のrouterオプションに作成したmiddlewareを定義していきます。これでmiddlewareで作成した処理がが使えるようになります。 【nuxt.config.js】
export default {
  .......
  router: {
    middleware: 'routing'
  }
  .......
}
  実際にページ遷移時に処理が行われることが確認できます。middlewareで使う関数にある引数の「context」オブジェクトにはstoreやrouteの情報が含まれており、middlewareから参照することができます。例えば下記のようにmiddlewareからdispatchを実行することで、storeの値を更新することができます。
import { Middleware, NuxtAppOptions } from '@nuxt/types'

const routing: Middleware = ({ app }: NuxtAppOptions) => {
  app.store.dispatch('ACTIONS_FUNCTION')
}

export default routing
  引数のappはコンテキストオブジェクトに含まれるキーでstoreなどにアクセスすることができます。この時に分割代入をすることで「context.app」のように書く必要がなくシンプルに使うことができます。  
アンカーリンクへのスクロール遷移
これを応用すると、アンカーリンクへのスクロール遷移を実装することができます。Nuxt.jsの場合、通常のアンカーリンクの設定ではなく、nuxt-linkを使ってハッシュの値を設定する必要があります。
<nuxt-link to="{ path: 'foo', hash: '#bar'}">アンカーリンク</nuxt-link>
  そして、middlewareでルーティングの情報が変わったタイミングでハッシュに対応するid属性を持つ要素の位置までスクロールさせるように処理を記述します。 【middleware/routing.ts】
import { Middleware, NuxtAppOptions } from '@nuxt/types'

const routing: Middleware = ({ route }: NuxtAppOptions) => {
  if(route.hash) {
    setTimeout(() => {
      const hashElememt: HTMLElement = document.querySelector(route.hash) as HTMLElement
      scrollTo(0, window.pageYOffset + hashElememt.getBoundingClientRect().top)
    }, 100)
  }
}

export default routing
  ここでは、DOMの描画のタイミングによって、document.querySelector(route.hash)でnullになる場合があるのでsetTimeoutで調整するようにしています。  
ローディング画面をトップページの初回読み込み時のみ実行する
ウェブサイトの仕様でよくある、初回訪問時にトップページなどでローディング画面を表示させるケースです。middlewareでルーティングの情報を扱えるので、これを使ってトップページかどうかをチェックして、ローディング画面が表示されているかどうかのフラグを更新する形になります。このフラグはstateに値を持たせておくことでローディング画面のコンポーネントとして実装できますね。
import { Middleware, NuxtAppOptions } from '@nuxt/types'

const routing: Middleware = ({ app, route }: NuxtAppOptions) => {
  if(route.name !== 'index') {
    app.store.dispatch('loadingScreenComplete', true)
  }
}

export default routing
 
  middlewareはページ遷移のたびに呼ばれるので、ページ遷移時やページが表示される度に実行したい処理などに使うことができます。いろんな機能要件に対応することができるかと思いますので、Nuxt.jsのプロジェクトではぜひ活用していきたいですね。
  • はてなブックマーク
  • Pocket
  • Linkedin
  • Feedly

この記事を書いた人

Twitter

sponserd

    keyword search

    recent posts

    • Twitter
    • Github
    contact usscroll to top
      • Facebook
      • Twitter
      • Github
      • Instagram