入力値が保存されていない場合にダイアログを出したかったのですが調べていたら私のサイトの構造上はまることが多かったのでメモ(ドキュメントをよく見ろといったようなものでしたが)
特定のコンポーネント内で使用したいのでコンポーネント内ガードを使います。
ポイント
- パラメータまたはクエリの変更は enter/leave ナビゲーションガードをトリガーしない(ドキュメントに記載 今回はupdateを設定しました)
- ブラウザの閉じる、更新ボタンはVue Router側で制御できなさそうなので別途実装する必要がある
実装
判定用の入力値と保存値が同じか判定するフラグはここではthis.noticeFlag
としています。
beforeRouteUpdate
は不要な場合は不要です。
制御可能なダイアログはvuesaxを使っていますが、遷移を止める場合はnext(false)
を行わないといけないということが重要です。next()
を呼ばないだけでは止まりませんでした。
********.vue
module.exports = {
//~~~~~~~~~~~~~~~~~~~~~~~
beforeMount() {// createdだとまだthisが使えないので
window.addEventListener('beforeunload', this.leaveHandler);// ブラウザ閉じる機能制御
},
beforeRouteUpdate(to, from, next) {
// ページ遷移制御 入力と保存に差分があったらダイアログ
// queryの変更でトリガーする
this.leaveCheck(next);
},
beforeRouteLeave(to, from, next) {
// ページ遷移制御 入力と保存に差分があったらダイアログ
// queryの変更ではトリガーしない
this.leaveCheck(next);
},
methods: {
leaveHandler(event) {
// 入力と保存に差分があったらブラウザのダイアログ
if (this.noticeFlag) {
// event.preventDefault();
if (event.type === 'beforeunload') {
event.returnValue = 'true';
}
}
},
leaveCheck(next) {
if (this.noticeFlag) {
// ダイアログ表示
this.$vs.dialog({
type: 'confirm',
color: 'primary',
title: 'Notice',
text: '行った変更が保存されていない可能性があります。',
acceptText: 'OK',
accept: () => {
next();
},
cancel: () => {
next(false);
}
});
} else {
next();
}
},
//~~~~~~~~~~~~~~~~~~~~~~~
},
//~~~~~~~~~~~~~~~~~~~~~~~
}