Make組ブログ

Python、Webサービスや製品開発、ライブラリー開発についてhirokikyが書きます

Vue.js+VueRouterでページの離脱、再読込、別ルートへの移動時に警告を表示する

ページの離脱時に警告を表示するには、 beforeunload イベントを使えば簡単にできます。 ですが、Vue.jsでVueRouterを使っている場合、ページの移動で beforeunload イベントは発生しません。 理由はブラウザーの画面自体が切り替わっていないからです(ページの遷移はVueRouter, つまりJavaScriptが同一の画面内で制御している)。

WordPressやDropboxPaperも、ページ離脱時には confirm() やモーダル表示を使ってページ遷移時に警告を表示しています (もちろんbeforeunload時の警告も併用しています)。

Vue.js + VueRouterでページ離脱、再読込時に警告を表示する

以下のように beforeunload を使えば良いです(クロスブラウザー対応どうこうはうまく書き換えてください)。

  methods: {
    handler (event) {
      event.returnValue = "Data you've inputted won't be synced"
    }
  },
  created () {
    window.addEventListener("beforeunload", this.handler)
  },
  destroyed () {
    window.removeEventListener("beforeunload", this.handler)
  }

vue-prevent-unload というライブラリーもありますが、小さすぎる実装なので参考にするだけで良いでしょう。 必要なコンポーネントに処理を書くか、独自のvue-prevent-unloadのようなコンポーネントをプロジェクト以下に置いておけば十分です。 例えば以下のようなVueコンポーネントStopUnload.js としておくなどです(あくまで参考実装です)。

export default {
  name: 'StopUnload',
  props: ["stop"],
  render: () => null,
  methods: {
    handler (event) {
      if (this.stop) {
        event.returnValue = "Data you've inputted won't be synced"
      }
    }
  },
  created () {
    window.addEventListener("beforeunload", this.handler)
  },
  destroyed () {
    window.removeEventListener("beforeunload", this.handler)
  }
}

ページ遷移時にも警告をする

ただこれだけではVueRouterによるページの遷移時に警告が表示されません。 以下のようにVueコンポーネント内に beforeRouteLeave を書けばVueRouterでのページ移動を検知できます。

beforeRouteLeave (to, from, next) {
  let answer = window.confirm("Data you've inputted won't be synced, OK?")
  if (answer) {
    next()
  } else {
    next(false)
  }
}

router.vuejs.org

ただしこの場合、VueRouterの routes に登録されているVueコンポーネントに上記の処理を書いてください(Viewとしてのコンポーネントに書く)。 VueRouterに直接関係しないコンポーネントでは beforeRouteLeave は呼び出されません。なので上記で例示したStopUnoadコンポーネントbeforeRouteLeave を書いても機能しません。

windowのbeforeunloadと、beforeRouteLeaveを使うことで、Vue.js+VueRouterでSPAを作っているときもページの離脱時に警告を表示できます。

他のオススメ記事

blog.hirokiky.org