LoginSignup
9
10

More than 1 year has passed since last update.

[Nuxt3] ページ移動前に本当に移動していいか確認するcomposable

Last updated at Posted at 2022-05-22

はじめに

前回からファイル投稿フォーム的なものを作っています。ページを移動する前に入力内容が消えても構わないか、一旦確認する、よくある確認ダイアログを出したいです。これまたNuxt2での例はそれなりにあったものの、Nuxt3でやってみた例が見当たらなかったのでやってみました。composableっていう機能がなんかすごく便利だなって個人的に思ってるのでcomposableでやります。

開発環境

  • Nuxt 3.0.0-rc.1
  • Vuetify 3.0.0-beta.1

ほしいイメージ

ページ移動時にこれが出てほしい
image.png
ページリロード時にこれが出てほしい
image.png

結果

過程をいっぱい書いても 興味ない方も居ると思うので出来上がったものをまず置いときます

src/composables/use-confirm-unload.ts
import {
    onBeforeRouteLeave, onBeforeRouteUpdate, NavigationGuardNext
} from 'vue-router'

const confirmText = "入力内容は破棄されます、本当に移動してもよろしいですか?"

const confirmVueRouter = (next: NavigationGuardNext) => {
    const answer = window.confirm(confirmText)
    if (answer) {
        // ページを移動したら、確認ダイアログを表示しないよう戻す
        window.removeEventListener("beforeunload", confirmBrowserRouter)
        next()
    }
}
const confirmBrowserRouter = (e: BeforeUnloadEvent) => {
    e.preventDefault()
    e.returnValue = confirmText
}

export default function () {
    // Vue-routerでのページ移動時の確認ダイアログ発火
    onBeforeRouteLeave((_to, _from, next) => {
        confirmVueRouter(next)
    })
    onBeforeRouteUpdate((_to, _from, next) => {
        confirmVueRouter(next)
    })
    // ページリロード時の確認ダイアログ発火
    if (process.client) {
        window.addEventListener("beforeunload", confirmBrowserRouter)
    }
}
使用例
<script setup lang="ts">
// ページ移動前に確認をしたいページでこの関数を呼ぶだけ
useConfirmUnload()
</script>

過程

1: Vueの普通のやり方を調べる

window.addEventListener("beforeunload", 関数)
で ブラウザのページ遷移前に割り込みができ

onBeforeRouteLeave
で vue-routerのページ遷移前に割り込みができるらしい

2: Nuxt2でのやり方を調べる

既存のやり方を参考にさせて頂きました

3: next() 関数の型を調べる

2回書きたくなかったので 関数を引数として渡す関数を作りたく、
関数を引数に取るときの型定義ってどうするのか見てみた

ただ、VSCodeからnextの型定義まで移動したら 型がちゃんとexportされていたので
import { NavigationGuardNext } from 'vue-router' で 型をそのまま使えた。

4: Routerをcomposable上で触る例を調べる

まだいまいちcomposableの書き方がわからないので
NuxtのDiscussionから既存の例を参考にさせていただいた

5: 完成

以上でいい感じに動くのができました。
ただ、beforeUnloadで出すダイアログのメッセージは いつの間にか変更できない仕様になってたようで
自環境では e.returnValueに何かが入っていれば規定の確認ダイアログが出るという振る舞いをしました。
まぁメッセージ変えられなくとも特に問題はないのでこれで完成とします。
読んでいただきありがとうございます。

9
10
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
10