🪧

【Vue】onBeforeRoute関連を使ったナビゲーションガードについてのまとめ

2024/02/18に公開

はじめに

最近ナビゲーションガードを実装する機会があった。
いろんなやり方があるが、今回は onBeforeRoute 関連を使用してのナビゲーションガードに関して自分なりにまとめる。

onBeforeRoute 関連は特定の component が存在する場合にナビゲーションガードを設定したい場合に使用する。
全体に設定したい方は下記などを覗いてみるといいかもしれない。

onBeforeRouteLeave

onBeforeRouteLeave はページを離れる場合の制御ができる。
例えば、特定のフォームが存在している場合に戻るボタンを押した際の制御が可能である。
ページ遷移したらフォーム内のデータが消えちゃいますよ?みたいなアラートを出してユーザに確認させることもできる。
下記 DEMO では、index page に遷移する前にアラートが出ているのが確認できる。
ユーザが OK ボタンを押したら index page に遷移する。

  • DEMO
サンプルコード
sampleForm.vue
<script lang="ts" setup>
import { onBeforeRouteLeave } from "vue-router";

// ルートを離れる前の処理
onBeforeRouteLeave((to, from, next) => {
  const answer = window.confirm(
    "ページを離れますか?変更が保存されない可能性があります。"
  );
  if (answer) {
    next();
  } else {
    next(false);
  }
});
</script>

<template>
  <div>
    <h2>なんか適当なフォーム</h2>
    <form>
      <div>
        <label for="userName">名前</label>
        <input type="text" name="name" id="userName" placeholder="山田 太郎" />
      </div>
      <div>
        <label for="mailAddress">メールアドレス</label>
        <input
          class="inputs"
          type="email"
          name="email"
          id="mailAddress"
          placeholder="hoge@mail.com"
        />
      </div>
      <div>
        <input type="submit" value="送信する" />
      </div>
    </form>
  </div>
</template>

<style scoped>
input {
  border: 1px solid #000;
}
div + div {
  margin-top: 20px;
}
</style>

route1.vue
<script lang="ts" setup>
import sampleForm from "../components/sampeForm.vue";
</script>

<template>
  <div>
    <h1>ナビゲーションガードのデモのデモ</h1>
    <p>
      このページを離れるか、パラメータを変更する前に確認ダイアログが表示されます。
    </p>
    <div class="section01" id="section01">セクション01</div>
    <div class="section02" id="section02">セクション02</div>
    <div class="section03" id="section03">セクション03</div>
    <a href="#section01">セクション01へ移動</a><br />
    <NuxtLink to="/">index pageへ移動</NuxtLink>
    <!-- 適当なフォーム -->
    <sampleForm />
  </div>
</template>

<style scoped>
.section01 {
  height: 300px;
  background: blue;
}
.section02 {
  height: 500px;
  background: red;
}
.section03 {
  height: 300px;
  background: green;
}
</style>

onBeforeRouteUpdate

onBeforeRouteUpdate は同一コンポーネント内のルート変更(例えば、クエリパラメータやパスパラメータの変更)に反応できる。
下記は特定のセクションに遷移して onBeforeRouteUpdate を発動させた後の画面。
localhost:3000/route1 → localhost:3000/route1#section01

サンプルコード
sampleForm.vue
<script lang="ts" setup>
import { onBeforeRouteUpdate } from "vue-router";

// ルートが更新される前の処理(例: パラメータの変更)
onBeforeRouteUpdate((to, from, next) => {
  console.log("onBeforeRouteUpdate");
  next();
});
</script>

<template>
  <div>
    <h2>なんか適当なフォーム</h2>
    <form>
      <div>
        <label for="userName">名前</label>
        <input type="text" name="name" id="userName" placeholder="山田 太郎" />
      </div>
      <div>
        <label for="mailAddress">メールアドレス</label>
        <input
          class="inputs"
          type="email"
          name="email"
          id="mailAddress"
          placeholder="hoge@mail.com"
        />
      </div>
      <div>
        <input type="submit" value="送信する" />
      </div>
    </form>
  </div>
</template>

<style scoped>
input {
  border: 1px solid #000;
}
div + div {
  margin-top: 20px;
}
</style>


まとめ

上記のように特定の component が存在する場合にナビゲーションガードを設定する場合には便利な機能がある。
ページを離れる際にアラートを出して確認するもよし、データを保存する処理などを挟むだけもよしでいろんな使用シーンが考えられる。

Discussion