編集中のものがあったりして、保存されませんが、続けますか?という確認をするあれです。
Nuxt.jsで書きます。
ブラウザを閉じたり、リロードしたりしたとき
export default {
created () {
window.addEventListener("beforeunload", this.confirmSave);
},
destroyed () {
window.removeEventListener("beforeunload", this.confirmSave);
},
methods: {
confirmSave (event) {
event.returnValue = "編集中のものは保存されませんが、よろしいですか?";
},
}
}
もし、編集されている時だけ出す、のような分岐をする場合は、
confirmSave (event) {
if (this.formChanged){
event.returnValue = "編集中のものは保存されませんが、よろしいですか?";
}
},
returnValue
で設定したメッセージを表示できるのはIEだけのようです。
違うページに遷移しようとしたとき
export default {
beforeRouteLeave (to, from, next) {
const answer = window.confirm("編集中のものは保存されませんが、よろしいですか?")
if (answer) {
next()
} else {
next(false)
}
},
}
編集されている時だけ出す場合は、
export default {
beforeRouteLeave (to, from, next) {
if (this.formChanged){
const answer = window.confirm("編集中のものは保存されませんが、よろしいですか?")
if (answer) {
next()
} else {
next(false)
}
} else {
next();
}
},
}
beforeRouteLeave
を使うときは、next()
が必須です。どこにも遷移できなくなります。
また、beforeRouteLeave
はルートコンポーネントにしか書けないようで、サブコンポーネントに書いても呼ばれません。
mixinに書くのは問題ないです。
サブコンポーネントに記述をまとめている場合はちょっと面倒ですが、コンポーネントの参照を使って書くことができます。
ルートコンポーネント
<template>
<sub-component ref="subComponent" />
</template>
<script>
export default {
beforeRouteLeave (to, from, next) {
if (this.$refs.subComponent.formChanged){
const answer = window.confirm("編集中のものは保存されませんが、よろしいですか?")
if (answer) {
next()
} else {
next(false)
}
} else {
next();
}
},
};
</script>
コンポーネントの参照は、メソッドも可能なので、基本的に出来ないことはなさそうです。
ルートコンポーネントだけでしか使えないことがちょっと使いづらいかもしれません。
参考
https://blog.hirokiky.org/entry/2019/08/22/111031
https://ja.coder.work/so/vuejs2/724205
https://router.vuejs.org/ja/guide/advanced/navigation-guards.html