VueJs实现输入变更后检测页面切换/关闭并弹出警告
Hey there! I see you're trying to show a warning when the user tries to navigate away or close the browser after editing the input box. Your current code sets up the beforeunload listener, but it's missing two key pieces: detecting if the input was actually changed, and properly triggering the browser's native warning prompt. Let's fix this step by step.
The Issue with Your Current Code
Right now, your handlerClose function runs every time the page unloads, but it doesn't check if the input was modified. Also, modern browsers require specific handling in the beforeunload event to display the warning—just logging a message won't make the prompt appear.
Fixed Solution
Here's how to adjust your code to make it work as expected:
1. Add a "Dirty" State Tracker
First, add reactive variables to track the input's original value and whether it's been modified (we'll call this isDirty).
2. Listen for Input Changes
Bind an @input event to your <b-form-input> to update the isDirty flag whenever the user types or edits the content.
3. Update the beforeunload Handler
Modify the handler to only trigger the warning if isDirty is true. Modern browsers need you to set event.returnValue and return a non-empty string to show the native confirmation prompt.
Full Modified Code
<template> <b-form-group label="Name" label-for="name-input"> <b-form-input id="name-input" v-model="name" @input="markAsDirty" ></b-form-input> </b-form-group> </template> <script> export default { data() { return { name: '', originalName: '', // Store initial value to compare changes isDirty: false } }, created() { // Save the initial input value when the component loads this.originalName = this.name; document.addEventListener('beforeunload', this.handlerClose); }, beforeDestroy() { // Clean up the event listener to avoid memory leaks document.removeEventListener('beforeunload', this.handlerClose); }, methods: { markAsDirty() { // Update dirty state only if current value differs from original this.isDirty = this.name !== this.originalName; }, handlerClose(event) { if (this.isDirty) { // Required for modern browsers to trigger the warning event.preventDefault(); event.returnValue = ''; // Return a string (some older browsers rely on this) return ''; } }, // Optional: Add this if you have a submit button to reset dirty state handleSubmit() { // Your form submission logic here this.originalName = this.name; this.isDirty = false; } } } </script>
Key Notes
- Memory Leak Prevention: Always remove the
beforeunloadevent listener in thebeforeDestroyhook—this avoids leaving unused listeners hanging around after the component is removed. - Resetting the Dirty State: If you have a form submission action, update
originalNameand setisDirtyback tofalseso the warning doesn't pop up after the user saves their changes. - Browser Compatibility: This approach works across all major modern browsers (Chrome, Firefox, Safari, Edge). Each browser might display a slightly different default warning message, but you can't customize this text for security reasons.
内容的提问来源于stack exchange,提问作者Beusebiu

