Is there a way to replicate onbeforeunload in a Vue.js 2 application?

I have a Vue component that is monitoring whether it has unsaved changes. I want to alert the user before they move away from the current form if there are unsaved modifications. In a traditional web application, you could use onbeforeunload. I tried implementing it in the mounted hook like this:

mounted: function(){
  window.onbeforeunload = function() {
    return self.form_dirty ? "If you leave this page, your unsaved changes will be lost." : null;
  }
}

However, this approach does not work when using Vue Router. It allows navigation through router links without warning, but triggers the alert when attempting to close the window or go to an external link.

Is there a way to simulate the behavior of onbeforeunload in a Vue application for both regular links and router links?

Answer №1

To ensure users do not accidentally leave a route with unsaved edits, utilize the beforeRouteLeave in-component guard in conjunction with the beforeunload event.

This guard is commonly employed to intercept user exits and offers the ability to cancel navigation by invoking next(false).

Within your component definition, follow these steps:

beforeRouteLeave (to, from, next) {
  // Check for dirty form and unconfirmed leave before allowing navigation
  if (this.confirmStayInDirtyForm()){
    next(false)
  } else {
    // Proceed to next view
    next()
  }
},

created() {
  window.addEventListener('beforeunload', this.beforeWindowUnload)
},

beforeDestroy() {
  window.removeEventListener('beforeunload', this.beforeWindowUnload)
},

methods: {
  confirmLeave() {
    return window.confirm('Do you really want to leave? you have unsaved changes!')
  },

  confirmStayInDirtyForm() {
    return this.form_dirty && !this.confirmLeave()
  },

  beforeWindowUnload(e) {
    if (this.confirmStayInDirtyForm()) {
      // Prevent default action
      e.preventDefault()
      // Set returnValue for Chrome compatibility
      e.returnValue = ''
    }   
  },
},

Answer №2

To successfully replicate this functionality, you can implement the following approach:

{
  methods: {
    handleBeforeUnloadEvent (event) {
      if (this.isFormDirty) {
        event.preventDefault()
        event.returnValue = ''
      }
    }
  },
  beforeRouteLeave (to, from, next) {
    if (this.isFormDirty) {
      next(false)
      window.location = to.path // Utilizing this technique
    } else {
      next()
    }
  },
  created () {
    window.addEventListener('beforeunload', this.handleBeforeUnloadEvent)
  },
  beforeDestroy () {
    window.removeEventListener('beforeunload', this.handleBeforeUnloadEvent)
  }
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Utilizing EJS to display dynamic data from a JSON file in a visually appealing D

*Excited about learning express! Currently, I have two files - index.ejs and script.js. The script I've written successfully fetches JSON data from an api. const fetch = require("node-fetch"); const url = '...' fetch (url) .then(resp ...

What is the method for entering a value in Code Mirror using Selenium WebDriver?

Struggling with inserting input values into Code Mirror, which is HTML code. Any assistance would be greatly appreciated! This is what I have been attempting so far (but I need to insert values on each line of Code Mirror) JavascriptExecutor js = (Javas ...

Switch the view to a grid layout upon clicking

Using bootstrap 5, I've successfully created a list view: <div class="col"> Click to switch to grid/list </div> Below is the content list: <div class="row mt-3 list"> list view ... ..... ....... </div ...

Tips for tracking advertisement views and saving them in a database

We recently placed our website advertisement on 2 different websites and are interested in tracking the number of clicks or hits we receive from those ads. We would like to store this data in our database. Can anyone suggest a method for accomplishing th ...

Enhance a portion of your text with some flair

Is it possible to apply styles to specific parts of text that are within an <input> value or a <span> element? For instance, I have the following data: {text text} an other text... I want to add styles to the text enclosed within {}. Here i ...

Creating Your Own Image Hosting Website: Learn how to consistently display an HTML file with a specific image from the URL

I'm currently in the process of developing my own image hosting site at Everything is functioning as intended, but I am looking to make a change. Currently, when a shared image link is opened, it only displays the image. However, I would like it to ...

Discovering the value of an HTML element node in the TinyMCE editor through the use of JavaScript or jQuery

Is there a way to retrieve the node name value using JavaScript or jQuery within the TinyMCE editor? Currently, I am only able to access the nodeName using the code snippet below: var ed = tinyMCE.activeEditor; var errorNode = ed.selection.getNode().node ...

How can Cheerio help you effortlessly and stylishly locate tags that meet various specific criteria?

I am attempting to scrape data from the webpage . Specifically, I am looking for all the <li> tags that are nested within an <ul> tag, which in turn is located inside a div with the class mw-parser-output and has a property of title. Is there ...

Switching between play and pause for the video element using a component for the child

Trying to toggle the play/pause of a child video by clicking on a parent div can be challenging, especially when dealing with multiple instances of the same div and video. A normal function may only work for one specific video, as mentioned by @ken. I hav ...

Unusual shadow cast by the box's silhouette

I am currently facing an issue with a box and its shadow. When I close the box, a different shadow lingers behind. I have tried troubleshooting this problem but cannot pinpoint the source. I have included the relevant code files in the specified folders. I ...

Interact with jQuery to trigger events upon clicking on a list item, excluding checkboxes within the list

I'm in the process of developing a straightforward web application. I have a dynamically generated list on one section: Subsequently, I set up an event that triggers when any element within the list is clicked: $(document).on('click', &apo ...

Express causing textarea in http form to have empty req.body

Here is a form for users to upload a file and submit text: form(action='/createpost' enctype="multipart/form-data" method='post' id="imgForm") input(type='file' name='imgPath' size = "60") br textarea(na ...

The method "_super" is not supported by the object in igGrid

When using infragistics and igGrid in my application, I encountered a javascript error. The error message reads: "Object doesn't support property or method "_super" Although I understand how to resolve this issue, I have decided to provide a fake ...

Analyzing an Object through Functions

var Car = function(name, year) { this.name = name; this.year = year; this.print = function() { console.log(name+" "+year); } } var tesla = new Car("tesla", 2018); tesla.print(); tesla = JSON.parse(JSON.stringify(tesla)); console.l ...

Which event listener in the DOM API should I use to trigger an action when a form field is focused, whether through a mouse click or by tabbing?

My aim is to increase the size of form fields when the cursor focuses on them, either through a mouse click or by tabbing using the keyboard. By utilizing document.activeElement focus, I can identify when the user clicks inside a text input or selects an ...

Encountering an issue with getDerivedStateFromProps in React where an error states: Unable to retrieve property 'setState' of null

Just found out that componentWillReceiveProps is deprecated and now we should be using the getDerivedStateFromProps lifecycle method. You can find more information about it at this link. This is how I'm implementing it: class Main extends Component ...

Unable to get jQuery waypoints to function on local server

Currently, I am working with jQuery. I downloaded an example shortcut for infinite scroll from jQuery Waypoints and tried to use it. However, when the page reaches the end, the web console displays the following error: XMLHttpRequest cannot load file:// ...

How to integrate a While loop within an RXJS subscription

I have a piece of Angular code where I am attempting to subscribe to my first API and include a while loop within this subscription. Additionally, I need to subscribe to another API inside the while loop. The reason for this is that I need to subscribe t ...

Retrieving data from Firestore yields an empty result

Having trouble reading from Firestore within a function, even though writes are working fine. Despite following examples on the given link, the query below and its variations result in an empty promise: module.exports.customerByPhone = phone => { r ...

In JavaScript, you can verify whether the content or blank space of an element was clicked

Is it possible to determine if the clicked part of an element is text or white space? https://i.sstatic.net/0pFgB.jpg My attempts so far have been unsuccessful: body.addEventListener('contextmenu', (e) => { e.preventDefault(); // Prevent ...