ページの離脱時に警告を表示するには、 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) } }
ただしこの場合、VueRouterの routes
に登録されているVueコンポーネントに上記の処理を書いてください(Viewとしてのコンポーネントに書く)。
VueRouterに直接関係しないコンポーネントでは beforeRouteLeave
は呼び出されません。なので上記で例示したStopUnoadコンポーネントに beforeRouteLeave
を書いても機能しません。
windowのbeforeunloadと、beforeRouteLeaveを使うことで、Vue.js+VueRouterでSPAを作っているときもページの離脱時に警告を表示できます。