在你的 Vue.js 组件中,你已经实现了对页面刷新的检测和关闭窗口时的处理,但可能会遇到一些问题,例如在刷新页面时也执行了注销操作。这是因为你在 beforeunload
事件中进行了一些逻辑判断,而这些逻辑可能未能正确区分刷新与关闭窗口的行为。
让我们来优化一下这部分代码,以便能够更清晰地识别用户是否是在刷新页面,而不是直接关闭浏览器:
优化建议
- 利用 Performance API 检测页面类型:使用
performance.getEntriesByType('navigation')
来检测导航类型,进而决定如何处理beforeunload
事件。 - 增强状态管理:确保每次加载后都设置好状态,并且当状态表明是刷新时,避免不必要的注销操作。
改进后的代码
以下是改进过的代码示例:
<template>
<div id="app">
<router-view />
</div>
</template>
<script>
import api from '@/store/api';
export default {
name: 'App',
data() {
return {
isReload: false,
};
},
computed: {
assetTag() {
return this.$store.getters['global/assetTag'];
},
},
watch: {
assetTag(tag) {
if (tag) {
document.title = `${tag} - ${this.$route.meta.title}`;
}
},
$route(to) {
document.title = to.meta.title || 'Page is missing title';
if (this.assetTag) {
document.title = `${this.assetTag} - ${to.meta.title}`;
}
},
},
created() {
document.title = this.$route.meta.title || 'Page is missing title';
let icoFlag = localStorage.getItem('CustomWebLogo');
var link =
document.querySelector("link[rel*='icon']") ||
document.createElement('link');
link.type = 'image/x-icon';
link.rel = 'shortcut icon';
link.href = `${icoFlag}.ico`;
document.head.appendChild(link);
this.$store.dispatch('authentication/twoFactorLogin').then(() => {
this.$router.push('/');
});
// 检测页面是否为重新加载
this.detectPageReload();
},
mounted() {
window.addEventListener('beforeunload', this.handleBeforeUnload);
},
beforeDestroy() {
window.removeEventListener('beforeunload', this.handleBeforeUnload);
},
methods: {
detectPageReload() {
const navEntries = performance.getEntriesByType('navigation');
const isReload =
navEntries.length > 0 && navEntries[0].type === 'reload';
// 如果是刷新,则设置标记
if (isReload) {
sessionStorage.setItem('isPageReload', 'true');
// 短暂延迟后清除标记,防止关闭误判
setTimeout(() => sessionStorage.removeItem('isPageReload'), 50);
}
},
handleBeforeUnload(event) {
const isReload = sessionStorage.getItem('isPageReload');
// 强制触发浏览器默认弹窗
event.preventDefault();
event.returnValue = '';
if (!isReload) {
// 执行关闭窗口时的退出操作
this.logoutUser();
} else {
// 清除标记,表示该次 unload 是由于刷新引起的,不做任何操作
sessionStorage.removeItem('isPageReload');
}
},
logoutUser() {
api.post('/logout', { data: [] });
sessionStorage.removeItem('TOKEN');
localStorage.removeItem('storedUsername');
},
},
};
</script>
<style lang="scss">
@import '@/assets/styles/_obmc-custom';
</style>
修改要点:
- 状态管理:确保在
detectPageReload()
中准确设置和清除刷新标记。 - 事件处理:在
handleBeforeUnload()
中,如果检测到是重载(即页面刷新的情况),则只需清除标记并返回,不执行注销操作。 - 不必要的监听器:移除了对
load
的监听,因为你的需求主要集中在监听页面卸载。
这样一来,当用户尝试离开页面时,通过设定好的机制,你可以更准确地判断他们是在进行何种操作,从而作出相应的响应。
内容由零声教学AI助手提供,问题来源于学员提问