43

I have an UnsavedChangesModal as a component that needs to be launched when the user tries to leave the page when he has unsaved changes in the input fields (I have three input fields in the page).

components: {
    UnsavedChangesModal
},
mounted() {
    window.onbeforeunload = '';
},
methods: {
   alertChanges() {

   }
}
Bargain23
  • 1,863
  • 3
  • 29
  • 50
  • 2
    vue-router have `beforeRouteLeave` hook – sfy Jul 25 '17 at 04:25
  • 2
    1. You can use vue lifecycle method - "beforeDestroy " hook as well and add a popup/dailog box before leaving page. 2 . You can use Vue-router BeforerouteLeave or use watch property on path. – Pallav Chanana Apr 27 '20 at 13:36

3 Answers3

83

Assuming you're using vue-router (and you probably should be), then you'll want to use the beforeRouteLeave guard. The documentation even gives an example of this exact situation:

beforeRouteLeave (to, from , next) {
  const answer = window.confirm('Do you really want to leave? you have unsaved changes!')
  if (answer) {
    next()
  } else {
    next(false)
  }
}

That can be added directly right on your component:

components: { ... },
mounted: { ... }
methods: { ... },
beforeRouteLeave (to, from, next) { ... }
DaveS
  • 3,156
  • 1
  • 21
  • 31
jpschroeder
  • 6,636
  • 2
  • 34
  • 34
  • Does this works when navigating to another website / closing the browser tab as well? – Ziad Akiki Jan 03 '19 at 16:15
  • 1
    @ZiadAkiki it doesn't block them for me no. – James Hall Jan 13 '19 at 23:20
  • upvoted! what to do if I am not using the Vue router – PirateApp Feb 06 '19 at 15:10
  • 2
    If you aren't using vue router then youll have to just bind to the window with: `window.onbeforeunload = () => 'Are you sure you want to leave?'` – jpschroeder Feb 06 '19 at 22:40
  • @jpschroeder how can be it used for such a scenario? Let's say you have a route /settings/:productId then made changes for that selected product and from drop down tried to to select another product then how can dialog be implemented in this case? Since only id was changed. Because above solution didn't work. – NewTech Lover Jul 16 '20 at 19:16
  • 4
    If anyone else reads this and wants a working Vue example which works even when closing the page. [See this answer](https://stackoverflow.com/a/56551646/8150685) – Error - Syntactical Remorse Apr 22 '21 at 12:43
  • @NewTechLover you can handle using "beforeRouteUpdate" method for dynamic route params – pavan kumar Jun 10 '21 at 17:15
18

These answers only cover navigation within Vue. If the user refreshes the page or navigates to a different site, that will not be caught. So you also need something like:

window.onbeforeunload = () => (this.unsavedChanges ? true : null);
Dirigible
  • 1,749
  • 16
  • 11
5

Are you using vue-router? I would look into navigation guards. I keep them in mind, but haven't used them myself yet. Here's the documentation on them: https://router.vuejs.org/guide/advanced/navigation-guards.html

DaveS
  • 3,156
  • 1
  • 21
  • 31